HDOJ 2191 珍惜现在,感恩生活(多重背包)
来源:互联网 发布:读诗书明德知礼下联 编辑:程序博客网 时间:2024/05/19 18:39
- 题目描述
- 题目大意
- 题目分析
- AC代码
- 对每种大米进行袋数次01背包
- 先拆分再求值
- 边拆分边求值
原题链接
题目描述
题目大意
给定经费n和买大米的种类m,以及每种大米每袋的价格,每袋的重量,袋数。求能购买大米的最大重量
题目分析
题目中给定了每种大米的袋数,不同于01背包中“要么取要么不取”的特点,也不符合完全背包中“可以取任意多次”的特点,而符合这种特点的背包就叫多重背包。
这个时候我们有两种做法:
- 对每种大米,进行“袋数”次01背包
- 对每种大米进行二进制拆分,转换成多个物品,然后进行01背包
例如本题中,对含有C袋大米的大米种类,可以拆分成由1袋,2袋,…, 2^(k)袋,C-2^(k)袋组成的新的大米种类。
具体实现见代码。
AC代码
对每种大米,进行“袋数”次01背包
#include <iostream>#include <algorithm>#include <vector>#include <stack>#include <string>#include <cmath>#include <cstring>using namespace std;const int INF = 0x3F3F3F3F;int dp[105];int v[105], w[105], num[105];int main() { int C, N, M; scanf("%d", &C); while (C--) { scanf("%d%d", &N, &M); for (int i = 1; i <= M; ++i) { scanf("%d%d%d", &v[i], &w[i], &num[i]); } memset(dp, 0, sizeof(dp)); for (int i = 1; i <= M; ++i) { for (int j = 1; j <= num[i]; ++j) { for (int k = N; k >= v[i]; k--) { if (dp[k] < dp[k - v[i]] + w[i]){ dp[k] = dp[k - v[i]] + w[i]; } } } } printf("%d\n", dp[N]); } return 0;}
先拆分,再求值
#includestruct Node{ int v; int w;} f[2000]; // int dp[105];int main() { int T, N, M; scanf("%d", &T); while (T--) { scanf("%d%d", &N, &M); int count = 0; for (int i = 0; i < M; i++) { int v, w, k; scanf("%d%d%d", &v, &w, &k); int c = 1; while (k - c > 0) { // split k to logk(+1) stuffs,so c*2. f[++count].v = c * v; f[count].w = c * w; k -= c; c *= 2; } f[++count].v = k*v; f[count].w = k*w; } memset(dp, 0, sizeof(dp)); for (int i = 1; i <= count; ++i) { // now it's a 0-1 backpack problem. for (int k = N; k >= f[i].v; k--) { dp[k] = max(dp[k], dp[k- f[i].v]+f[i].w); } } cout << dp[N] << endl; } return 0;}
边拆分,边求值
#includeint dp[105];int v[105], w[105], num[105];int main() { int T, N, M; scanf("%d", &T); while (T--) { scanf("%d%d", &N, &M); for (int i = 1; i <= M; ++i) { scanf("%d%d%d", &v[i], &w[i], &num[i]); } memset(dp, 0, sizeof(dp)); for (int i = 1; i <= M; ++i) { for (int j = 1; j <= num[i]; j *= 2) { for (int k = N; k >= j*v[i]; k--) { dp[k] = max(dp[k], dp[k-j*v[i]]+j*w[i]); } num[i] -= j; } for (int k = N; k >= num[i] * v[i]; k--) { dp[k] = max(dp[k], dp[k-num[i]*v[i]]+num[i]*w[i]); } } printf("%d\n", dp[N]); } return 0;}
阅读全文
0 0
- HDOJ 2191 珍惜现在,感恩生活(多重背包)
- 珍惜现在,感恩生活(多重背包)
- HDU 2191 珍惜现在,感恩生活(多重背包)
- [ACM] hdu 2191 珍惜现在,感恩生活 (多重背包)
- HDU 2191 珍惜现在,感恩生活(多重背包)
- HDU 2191 珍惜现在,感恩生活 (多重背包)
- 珍惜现在,感恩生活-多重背包问题
- HDOJ 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 (多重背包)
- HDOJ 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 【多重背包】
- HDOJ 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 (多重背包)
- HDOJ 题目2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包问题)
- 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(hdoj--2191--多重背包)
- hdoj 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
- HDOJ 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
- Hdu 2191 珍惜现在,感恩生活 (多重背包)
- HDU 2191 珍惜现在,感恩生活 多重背包 .
- hdoj 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 【多重背包】【01-背包】
- hdoj 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 【多重背包 01背包】
- c++实训单元五-自定义数据类型
- Redis主从复制
- 优化Trunk
- 【Lua】Lua之面向对象
- Oracle PL/SQL开发基础(第二十二弹:类型转换函数)
- HDOJ 2191 珍惜现在,感恩生活(多重背包)
- 配置python环境变量
- Idea 调试功能使用指南
- 数据交互vue-resource
- matlab数据类型(数值类型)
- (OK)(OK) Android-x86-7.1.1/ kernel 4.4.62
- Kotlin-31.操作符/运算符重载(operator overload)
- 【dp每一天】 POJ
- php7 新特性整理