【POJ3093】Margaritas on the River Walk【01背包变种】
2016-04-03 22:56
405 查看
【题目链接】
大意:给定一个容量为V的背包和N件物品各自的体积,求有多少种方法使得背包再也装不下任何物品。
论文题,见《浅谈几类背包题》徐持衡。
另外这篇题解写得不错【浙西贫农的题解】
一开始不理解为什么这样做可以保证不取前面的物品,最后发现倒着循环时,dp还没有统计前面物品的方法数...
/* Pigonometry */
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 35, maxv = 1005;
int n, m, w[maxn], sum[maxn], dp[maxv];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
int main() {
int T = iread();
for(int cas = 1; cas <= T; cas++) {
n = iread(); m = iread();
for(int i = 0; i <= m; i++) dp[i] = 0;
for(int i = 1; i <= n; i++) w[i] = iread();
sort(w + 1, w + 1 + n);
for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + w[i];
if(w[1] > m) {
printf("%d 0\n", cas);
continue;
}
int ans = 0; dp[0] = 1;
for(int i = n; i >= 1; i--) {
int left = m - sum[i - 1];
for(int j = max(0, left - w[i] + 1); j <= left; j++)
ans += dp[j];
for(int j = m; j >= w[i]; j--)
dp[j] += dp[j - w[i]];
}
printf("%d %d\n", cas, ans);
}
return 0;
}
大意:给定一个容量为V的背包和N件物品各自的体积,求有多少种方法使得背包再也装不下任何物品。
论文题,见《浅谈几类背包题》徐持衡。
另外这篇题解写得不错【浙西贫农的题解】
一开始不理解为什么这样做可以保证不取前面的物品,最后发现倒着循环时,dp还没有统计前面物品的方法数...
/* Pigonometry */
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 35, maxv = 1005;
int n, m, w[maxn], sum[maxn], dp[maxv];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
int main() {
int T = iread();
for(int cas = 1; cas <= T; cas++) {
n = iread(); m = iread();
for(int i = 0; i <= m; i++) dp[i] = 0;
for(int i = 1; i <= n; i++) w[i] = iread();
sort(w + 1, w + 1 + n);
for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + w[i];
if(w[1] > m) {
printf("%d 0\n", cas);
continue;
}
int ans = 0; dp[0] = 1;
for(int i = n; i >= 1; i--) {
int left = m - sum[i - 1];
for(int j = max(0, left - w[i] + 1); j <= left; j++)
ans += dp[j];
for(int j = m; j >= w[i]; j--)
dp[j] += dp[j - w[i]];
}
printf("%d %d\n", cas, ans);
}
return 0;
}
相关文章推荐
- hdu 1203 I NEED A OFFER! 01背包
- poj 1159 Palindrome dp 字符串
- 我该如何向我的朋友解释“01背包”问题?
- 01背包问题
- hdu 2546 饭卡 (01背包)
- hdu 2602 Bone Collector (01背包 )
- hdu 2639 Bone Collector II (01背包,第k优解问题)
- [01背包]NOIP2001 PJ T4 装箱问题
- [01背包]NOIP 2005 PJ T3 采药 + 01背包的空间优化
- 01背包问题
- 01背包详解(ZeroOnePack)
- XX采药
- poj_1837
- nyoj开心的小明
- 背包问题1:01背包
- hdu1203 — I NEED A OFFER! (01背包)
- hdu2602 — Bone Collector
- hdu1864 — 最大报销额
- hdu2546 — 饭卡 (01背包)
- hdu2955 — Robberies (01背包)