-
L - Coin Change
UVA - 674 - 看完这个问题,你也许会觉得这个不就是01背包的升级版吗,其实就是这样,完全背包问题与01背包问题的区别在于完全背包每一件物品的数量都有无限个,而01背包每件物品数量只有1个
- 所以说与它相关的策略已经不是只有取和不取这两种策略了,而是有取0件、取1件、取2件……等等很多种策略
-
下面给出状态转移方程:
f[i][j] = max{f[i][j],f[i-1][j - k * c[i]] + k * w[i]}(0<=k*c[i]<=v)
-
我们现在dp每一个物品,dp出该种物品在不同剩余容量下的最优解,他是以每1个为单位的。考虑是否在当前所有物品总数中添加一件新的该物品
我们用i代表前i种物品,v代表包的最大承重,c[i]是第i种物品消耗的空间、w[i]是第i种物品的价值、f[i,j]是最大价值(从前i种物品取若干件放入有j个剩余空间的包)。
如果不放那么f[i][j]=f[i-1][j]
如果确定放,那么f[i][j]=f[i][j-c[i]+w[i]]
-
因为第i种物品一旦出现,原来没有第i种物品的情况下可能有一个最优解,现在第i种物品 出现了,而它的加入有可能得到更优解,所以之前的状态需要进行改变,故需要正序。
-
for (int i = 1; i <= n; ++i) for (int j = w[i]; j <= v; ++j) f[j] = max(f[j], f[j - c[i]] + v[i]);
#include <cstdio> #include <cstring> #include <bits/stdc++.h> using namespace std; const int N = 7500; int val[5] = {1,5,10,25,50}; int n; int dp[N]; int main() { while (cin>>n) { memset(dp, 0, sizeof(dp)); dp[0] = 1; for (int i = 0; i < 5; i++) for (int j = val[i];j <= n; j++) dp[j] += dp[j - val[i]]; printf("%d\n", dp[n]); } return 0; }
L - Coin Change-种类型完全背包
最新推荐文章于 2022-05-25 11:52:12 发布