题意
给我们一个容器的容量m n个物品 每个物品有不同的花费和价值 问我们再每个物品无限个的情况下 最后正好装满最后得到的最小价值是多少 如果装不满 就输出impossible
分析
目标状态:最小价值策略
限制条件:正好装满m的容量
多重背包模型
每个物品可以选择无限个 但是又要求恰好装满
满足最小价值策略我们应该取min 所以应把结果数组初始化无穷大 不然无法选出最小值
遵循递推式为dp[i] = min(dp[i],dp[i-cost[x]]+value[x]的选择策略
但是设置inf后发现我们每次操作的元素都是inf 其中最小的元素也就是inf无法得到正解
所以把dp[0]初始化为0,其他位置inf
因为只有把dp[0]初始化为0
我们在递推式中不断选择物品才能将dp数组更新 不然永远为inf
最后如果能装到m的位置m必然不等于inf
而且会不断取最小
都是从dp[0] = 0扩展出来的
所以为了最小策略我们需要不断取最小
code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int w[510],p[510];
typedef long long ll;
const ll inf = (1<<31)-1;
ll dp[10010];int main()
{
// cout<<inf<<endl; int t;scanf("%d",&t);while(t--){int e,f;scanf("%d%d",&e,&f);int m = f-e;int q;scanf("%d",&q);for(int i=1;i<=q;i++)scanf("%d%d",&p[i],&w[i]);for(int i=1;i<=m;i++)dp[i] = inf;dp[0]=0;for(int i=1;i<=q;i++){for(int j=w[i];j<=m;j++){dp[j] = min(dp[j],dp[j-w[i]]+p[i]);}}if(dp[m]!=inf)printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m]);else printf("This is impossible.\n");memset(dp,0,sizeof(dp));}return 0;
}