POJ 1384
一道简单的完全背包,第一次的思路是正确的,但是由于疏忽,竟然将数组dp全部赋值为0,导致结果一直是0,进而怀疑自己的思路,于是走了许多弯路,后来才偶然发现应该将初值赋为无穷大(因为是求最小值),又犯了一次低级错误,下次应该注意!
状态转移方程:dp[j]=get_min( dp[j],dp[j-wgh_coins[i]]+val_coins[i])
由于是完全背包,所以第二重循环应该顺序而不是逆序。
另外,dp[0]的初值为0,注意边界条件:当i=1,j=wgh_coins[i]时,方程为dp[j]=get_min(dp[j],dp[0]+val_coins[i]),只有dp[0]=0时,才能得出正确结果。
#include<stdio.h> #define MAX_COINS_KIND 510 #define MAX_WEIGH 10010 #define INF 1000000 int get_min(int,int); int main() { int t; scanf("%d",&t); while(t--) { int wgh_epty,wgh_total,n,i,j,wgh_coins[MAX_COINS_KIND],val_coins[MAX_COINS_KIND],dp[MAX_WEIGH]; scanf("%d%d",&wgh_epty,&wgh_total); scanf("%d",&n);
dp[0]=0; for(i=1;i<MAX_WEIGH;i++) { dp[i]=INF; } for(i=1;i<=n;i++) { scanf("%d%d",&val_coins[i],&wgh_coins[i]); } for(i=1;i<=n;i++) { for(j=wgh_coins[i];j<=wgh_total-wgh_epty;j++) { dp[j]=get_min( dp[j],dp[j-wgh_coins[i]]+val_coins[i]); } } if(dp[wgh_total-wgh_epty]!=INF) { printf("The minimum amount of money in the piggy-bank is %d.\n",dp[wgh_total-wgh_epty]); } else { printf("This is impossible.\n"); } } return 0; } int get_min(int x,int y) { return x<=y?x:y; }