POJ 3093 背包 (技巧优化)
来源:互联网 发布:减速箱装配图 淘宝 编辑:程序博客网 时间:2024/06/15 19:22
参考:09年集训队论文《浅谈几类背包问题》 徐持衡
题意:多组输入,每组给定物品数(<=30)和背包容量(<=1000)以及接下来每个物品的体积,问有多少种方案,使得装入一些物品后,无法装入剩下的任意一个物品。
可以转化成0-1背包来做,首先按体积从小到大排序,枚举“剩下的物品”中体积最小的。剩下的物品中体积最小的为i时,前i-1个物品是必然被装入背包的,然后对第i+1到第n个物品做0-1背包问题,转移方程f[i][j]表示前i个物品装入容量为j的背包的方案数,f[i][j] = f[i-1][j] + f[i-1][j-v[j]]。那么便有了这个O(T*n*n*C)的做法。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int T, n, m, sum, v[33];long long ans, f[1005];int main (){ scanf ("%d", &T); for (int num = 1; num <= T; num++) { sum = ans = 0; scanf ("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf ("%d", v+i); sort(v+1, v+n+1); if (v[1] > m) {printf ("%d 0\n", num); continue;} for (int i = 1; i < n; i++) { if (sum > m) break; memset (f, 0, sizeof f); f[sum] = 1; for (int ii = i+1; ii <= n; ii++) { for (int j = m; j >= v[ii]+sum; j--) f[j] = f[j] + f[j-v[ii]]; } int tmp = max(m-v[i]+1,sum); for (int j = tmp; j <= m; j++) ans += f[j]; sum += v[i]; } printf ("%d %lld\n", num, ans); } return 0;}
可以考虑一个优化。在之前的做法中,每个物品都被多次考虑装入背包,n-1次。稍微改一下细节做法,之前的做法是f[sum] = 1,背包容量仍然为C,可以改成f[0] = 1,背包容量为C-sum。那么就可以“倒着来”,在我们倒序枚举物品i装入背包的同时,也就相当于第i-1个物品为最小的剩下的物品,而i-2之前都被装入。对于背包容量的变化,每次直接从最大容量C开始考虑即可。这样复杂度就是O(T*n*C)。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int T, n, m, sum, v[33];long long ans, f[1005];int getint (){ int x = 0; char c = getchar(); while (c < '0' || c > '9') c = getchar(); while (c <= '9' && c >= '0') x = x*10+c-48, c = getchar(); return x;}int main (){ T = getint(); for (int num = 1; num <= T; num++) { sum = ans = 0; memset (f, 0, sizeof f); f[0] = 1; n = getint(), m = getint(); for (int i = 1; i <= n; i++) sum += (v[i] = getint()); sort(v+1, v+n+1); if (v[1] > m) {printf ("%d 0\n", num); continue;} for (int i = n; i; i--) { sum -= v[i]; for (int j = 0; j < v[i] && m-sum-j >= 0; j++) ans += f[m-sum-j]; for (int j = m; j >= v[i]; j--) f[j] += f[j-v[i]]; } printf ("%d %lld\n", num, ans); } return 0;}
0 0
- POJ 3093 背包 (技巧优化)
- poj 1276(背包问题,二进制优化技巧)
- poj 1726 Cash Machine(背包+优化)
- poj-1742 Coins(多重背包优化)
- 【POJ】 1014 Dividing(多重背包,优化)
- POJ 题目3181 Dollar Dayz(完全背包,技巧)
- (优化的有限背包) poj 1742 Coins(转载)
- poj 1742coins(优化的多重背包)
- poj 1276 Cash Machine(多重背包+二进制优化)
- poj 2392 Space Elevator(未优化的多重背包)
- POJ 1742 Coins 多重背包(单调队列优化)
- POJ-1276 Alignment ( 多重背包)优化版
- POJ 1276Cash Machine(多重背包 + 二进制优化)
- POJ 1742 coins(背包+二进制优化+bitset)
- POJ 1276 Cash Machine (多重背包+技巧)【标记式背包】
- POJ 1276 Cash Machine (多重背包转01背包优化)
- POJ 1742(特别技巧之多重背包转完全背包)
- (优化的有限背包) poj 1742 Coins
- python异常处理
- hdoj 2032 杨辉三角
- Cocos2d-x:3.0和2.0之间的区别
- 从硬件负利到硬件免费,乐视用生态化反深度改造传统硬件行业
- PinnedSectionListView使用详解
- POJ 3093 背包 (技巧优化)
- 架构案例丨苏宁易购:商品详情系统架构设计
- Laravel 5.2 使用ckeditor
- 欢迎使用CSDN-markdown编辑器
- Java 单例
- IPv6地址表示方法
- 解决的计算器问题
- 集合框架的阅读技巧
- HTML简单表单