题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114
思路:
题目看着有些绕,其实就是完全背包的变形,需要注意的是这里求最小值,所以需要将dp数组初始化为inf,但要将dp[0]=0,这样才能将dp进行下去。还有就是dp处的双重循环的第二层循环应该从小到大遍历,因为这里的coin是种类,每一种可以使用无限次;若从大到小遍历就是每一种类只能使用一次,这个地方很重要,要慢慢体会,自己举个例子试试。详见代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int inf=0x3f3f3f3f; 5 int T,e,f,v,n; 6 int p[505],w[505],dp[10005]; 7 8 int main(){ 9 scanf("%d",&T); 10 while(T--){ 11 memset(dp,inf,sizeof(dp)); //求min,故初始化inf 12 dp[0]=0; 13 scanf("%d%d",&e,&f); 14 v=f-e; 15 scanf("%d",&n); 16 for(int i=1;i<=n;i++) 17 scanf("%d%d",&p[i],&w[i]); 18 for(int i=1;i<=n;i++) 19 for(int j=w[i];j<=v;j++) //这里的coin是种类,每种个数无限,应从小到大遍历 20 if(dp[j]>dp[j-w[i]]+p[i]) 21 dp[j]=dp[j-w[i]]+p[i]; 22 if(dp[v]<inf) 23 printf("The minimum amount of money in the piggy-bank is %d.\n",dp[v]); 24 else 25 printf("This is impossible.\n"); 26 } 27 return 0; 28 }