标签:
Description
Input
Output
Sample Input
Sample Output
初始化的细节问题:我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。有的题目要求“恰好装满背包”时的最优解,有的题目
则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。
如果是第一种问法,要求恰好装满背包,那么在初始化
时除了f[0]为0其它f[1..V]均设为-∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。
如果并没有要求必须把背包装满,而是只希
望价格尽量大,初始化时应该将f[0..V]全部设为0。
为什么呢?可以这样理解:初始化的f数组事实上就是在没有任何物品可以放入背包时的合法状
态。如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的
状态,它们的值就都应该是−∞了。如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,这个解的价值为0,所以初始时
状态的值也就全部为0了.
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <fstream> 5 using namespace std; 6 const int INF = 0x7ffffff; 7 int main() 8 { 9 int T; 10 cin>>T; 11 while(T--) 12 { 13 int x1,x2; 14 cin>>x1>>x2; 15 int dp[10001]; 16 int lose_w = x2 - x1; 17 int p[500+5],w[500+5]; 18 int n; 19 cin>>n; 20 for(int i = 0; i < n; i++) 21 { 22 cin>>p[i]>>w[i]; 23 } 24 /*初始化*/ 25 for(int i=1; i<=lose_w; i++) 26 dp[i]=INF; 27 dp[0]=0; 28 for(int i = 0; i< n; i ++) 29 for(int j = w[i]; j <= lose_w; j++) 30 { 31 dp[j] = min(dp[j],dp[j-w[i]]+p[i]); 32 } 33 if(dp[lose_w]==INF) 34 cout<<"This is impossible."<<endl; 35 else 36 cout<<"The minimum amount of money in the piggy-bank is "<<dp[lose_w]<<"."<<endl; 37 38 } 39 return 0; 40 41 }
1 /*借鉴的代码*/ 2 #include<stdio.h> 3 #include<string.h> 4 #define INF 0x7ffffff 5 #define MAXN 10000 6 int dp[MAXN+10];//dp[i]表容量为i的时候所装东西的最小价值 7 int main() 8 { 9 int w1,w2; 10 int P,W; 11 int T,n; 12 int i,j; 13 scanf("%d",&T); 14 while(T--) 15 { 16 scanf("%d%d",&w1,&w2); 17 scanf("%d",&n); 18 for(i=1;i<=w2-w1;i++) 19 dp[i]=INF;//初始化为无穷大 20 dp[0]=0; 21 while(n--) 22 { 23 scanf("%d%d",&P,&W); 24 for(i=W;i<=w2-w1;i++) //直接在读入中处理时间空间效率更高 25 if(dp[i]>dp[i-W]+P) 26 dp[i]=dp[i-W]+P; 27 } 28 if(dp[w2-w1]==INF) printf("This is impossible.\n"); 29 else 30 printf("The minimum amount of money in the piggy-bank is %d.\n",dp[w2-w1]); 31 } 32 return 0; 33 }
标签:
原文地址:http://www.cnblogs.com/cjshuang/p/4661059.html