题意 : 给你一个罐子的自身重量和它最大的承受重量,再给你n种面值的硬币,接下来n行为每个硬币的价值和重量,让你求能恰好装满罐子的最小价值 如果没办法恰好装满则输出This is impossible.
明显这是一个多重背包 我们知道完全背包的模板:
for i=1..N
for v=0..V
f[v]=max{f[v],f[v-c[i]]+w[i]};
但是这道题还要精确得出是否装满 若用上边的式子 无法判断 所以 可以将dp数组初始化为最大 每次更新时用min来更新 最后若dp[W]没有被更新到 则证明无法精确装满
如果不能刚好装满的话dp[W-k*w[i]]是不存在的为其初始值inf。那么dp[W]就永远无法更新W
代码:
#include<bits/stdc++.h>
using namespace std;
#define inf 999999
int T;
int dp[1000001];
int main(){
cin >>T;
int E, F, W;
int val[501], w[501];
while(T--){
cin >> E >> F;
W = F - E;
int n; cin >> n;
for(int i = 1; i < W +5; i++)
dp[i] = inf;
dp[0] = 0;
for(int i = 0; i < n; i++){
cin >> val[i] >> w[i];
}
for(int i = 0; i < n; i++){
for(int v = w[i]; v <= W; v++){
dp[v] = min(dp[v], dp[v-w[i]]+val[i]);
}
}
if (dp[W] == inf)
printf ("This is impossible.\n");
else
cout << "The minimum amount of money in the piggy-bank is " <<dp[W] <<'.' << endl;
}
}