-
F - Piggy-Bank
- HDU - 1114
- 基础版本:
-
f[i][j] = max{f[i][j],f[i-1][j - k * c[i]] + k * w[i]}(0<=k*c[i]<=v)
-
for (int i = 1; i < n; i++){ for (int j = 1; j <= v; j++){ for (int k = 0; k*c[i] <= j; k++){ if(c[i]<=j)/*如果能放下*/ f[i][j] = max{f[i][j],f[i-1][j - k * c[i]] + k * w[i]};/*表示前i-1种物品中选取若干件物品放入剩余空间为j-k*w[i]的背包中所能得到的最大价值加上k件第i种物品的总价值*/ else/*放不下的话*/ f[i][j]=f[i-1][j]/*继承前i-1个物品在当前空间大小时的价值*/ } } }
- 重复过程的利用:
-
f[i][j]=max(f[i-1][j],f[i][j-c[i]]+w[i])
- 因为第i种物品一旦出现,原来没有第i种物品的情况下可能有一个最优解,现在第i种物品 出现了,而它的加入有可能得到更优解,所以之前的状态需要进行改变,故需要正序。
- 所以说递推式是这样子的:
-
f[j] = max(f[j],f[j-c[i]]+w[i])
-
#include<bits/stdc++.h> using namespace std; #define maxn 11111 #define inf 0x3f3f3f3f int n,t,dp[maxn],e,f; int w[maxn],p[maxn]; int main() { scanf("%d",&t); while(t--) { scanf("%d%d",&e,&f); f-=e; scanf("%d",&n); for(int i=0; i<n; i++) scanf("%d%d",&p[i],&w[i]); for(int i=0; i<=f; i++) dp[i]=inf; dp[0]=0; for(int i=0; i<n; i++) for(int j=w[i]; j<=f; j++) dp[j]=min(dp[j],dp[j-w[i]]+p[i]); if(dp[f]==inf) printf("This is impossible.\n"); else printf("The minimum amount of money in the piggy-bank is %d.\n",dp[f]); } return 0; }
F - Piggy-Bank-完全背包
最新推荐文章于 2019-08-05 20:34:36 发布