完全背包的模版题..
加了一个小优化 n^2的写法 O(V+N)在本题中复杂度较高 不采纳
完全背包问题有一个很简单有效的优化,是这样的:若两件物品i、j满足c[i]<=c[j]且w[i]>=w[j],则将物品j去掉,不用考虑。这个优化的正确性显然:任何情况下都可将价值小费用高得j换成物美价廉的i,得到至少不会更差的方案。对于 随机生成的数据,这个方法往往会大大减少物品的件数,从而加快速度。然而这个并不能改善最坏情况的复杂度,因为有可能特别设计的数据可以一件物品也去不掉。
这个优化可以简单的O(N^2)地实现,一般都可以承受。另外,针对背包问题而言,比较不错的一种方法是:首先将费用大于V的物品去掉,然后使用类似计数排序的做法,计算出费用相同的物品中价值最高的是哪个,可以O(V+N)地完成这个优化。
上代码了 优化后跑的蛮快的
1 #include <stdio.h> 2 #include <iostream> 3 #include <algorithm> 4 #include <string.h> 5 #include <math.h> 6 #include <map> 7 #include <limits.h> 8 using namespace std; 9 const long long MOD = 1e9+7; 10 typedef long long ll; 11 int c[110],w[110]; 12 int f[100001]; 13 bool vis[110]; 14 15 int main() 16 { 17 int n,m; 18 while(scanf("%d",&n)!=EOF) 19 { 20 memset(f,0,sizeof(f)); 21 memset(vis,false,sizeof(vis)); 22 for(int i=0;i<n;i++) 23 { 24 scanf("%d%d",&w[i],&c[i]); 25 } 26 scanf("%d",&m); 27 /* 28 n^2 优化 29 */ 30 31 for(int x=0;x<n;x++) 32 { 33 for(int y=x+1;y<n&&vis[x]==false;y++) 34 { 35 if(c[x]<=c[y]&&w[x]>=w[y]) 36 { 37 vis[y] = true; 38 } 39 else{ 40 if(c[y]<c[x]&&w[y]>w[x]) 41 { 42 vis[x] = true; 43 } 44 } 45 } 46 } 47 for(int i=0;i<n;i++) 48 { 49 if(vis[i]) continue; 50 for(int j=c[i];j<=m;j++) 51 { 52 f[j] = max(f[j],f[j-c[i]]+w[i]); 53 } 54 55 } 56 printf("%d ",f[m]); 57 } 58 return 0; 59 }