您的位置:首页 > 其它

【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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  01背包