翻译:一个存钱罐,不打破存钱罐,计算其里面最少多少钱。
这是一个完全背包问题。因为每一种面额的钱都是可以无限次的使用。
数据T为测试的个数。E和F分别为空存储罐的重量和装满钱后的重量。
N为硬币种类个数,然后分别输入p[i]和w[i] (1<=i<=N) p为价值,
w为重量。
dp[v]=min{ dp[v] , dp[v-c[i]]+w[i] }
第一这个问题求的是最小值。第二 这个问题要求满足最后存钱罐是“装满”
因此在递推关系式 和 初始化的时候都需要注意。
#include<stdio.h>
#include<string.h>
const int INF=0XFFFFFF;
int main()
{
int T,E,F,N,p[510],w[510],dp[10000],V;
scanf("%d",&T);
while (T--)
{
//输入数据
scanf("%d%d",&E,&F);
V=F-E;
scanf("%d",&N);
for (int i=1;i<=N;i++)
scanf("%d%d",&p[i],&w[i]);
//数据初始化。dp[0]=0 dp[1...]=INF
for(int j=0;j<=V;j++)
dp[j]=INF;
dp[0]=0;
//利用递推关系
for(int i=1;i<=N;i++)
for(int j=w[i];j<=V;j++)
dp[j]=dp[j]>dp[j-w[i]]+p[i]?dp[j-w[i]]+p[i]:dp[j];
if(dp[V]!=INF)
printf("The minimum amount of money in the piggy-bank is %d.
",dp[V]);
else
printf("This is impossible.
");
}
return 0;
}
关于初始化的一点说明《背包九讲》有涉及:
如果题目不要求要把背包装满,只是要求获得效益最大,那么初始化都是dp[0.....V]=0
如果题目要求将背包装满,那么dp[0]=0 dp[1....V]=-INF
本题属于第二种情况,需要将背包装满,同时又是求取的最小值,故dp[0]=0 dp[1....V]=INF