HDU3535 AreYouBusy 混合分组背包
2011-08-11 15:53
267 查看
Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=3535
【思路】
这是一道分组背包的题目。
s分别取0、1、2时代表三种不同的背包。
只要对不同类型的背包进行不同的dp,则可得到结果。
(1)s取0时,表示该组里至少取一个。
转移方程为:dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j], dp[flag][k-w[j]]+v[j]);(其中flag表示当前组当前状态,1-flag表示上一组的最终状态。下同。)
这种情况下每个背包状态只能来源于当前组和上一组的k-w[j],而不能从上一组继承。所以要注意的是初始化,由于不能从上一组继承,所以应初始化为INT_MIN。
(2)s取1时,表示该组里至多取一个。
转移方程为:dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j]);
这种情况下每个背包状态是不能从当前组继承的,即只能从上一组转移过来。所以初始化为上一组状态。
(3)s取2时,表示该组可以自由选择。
转移方程为:dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j], dp[flag][k-w[j]]+v[j]);(与s取0时相同。)
不过由于这种情况可以从当前组以及上一组继承,所以初始化为上一组状态。
最后结果还要和-1比较,取其大者。这是因为第一种情况初始值赋为INT_MIN的结果。
赋为INT_MIN的时候,如果该组的所有状态都取不到,那么结果肯定是会比-1小的。延续下去,最终结果也是比-1小,即这中状态是无法达到的。
【代码】
初始值赋为INT_MIN,则如果所有状态都取不到,结果就是INT_MIN,那么即使后面可以取到,这个值也是比-1小的,即这种状态是无法达到的。
【思路】
这是一道分组背包的题目。
s分别取0、1、2时代表三种不同的背包。
只要对不同类型的背包进行不同的dp,则可得到结果。
(1)s取0时,表示该组里至少取一个。
转移方程为:dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j], dp[flag][k-w[j]]+v[j]);(其中flag表示当前组当前状态,1-flag表示上一组的最终状态。下同。)
这种情况下每个背包状态只能来源于当前组和上一组的k-w[j],而不能从上一组继承。所以要注意的是初始化,由于不能从上一组继承,所以应初始化为INT_MIN。
(2)s取1时,表示该组里至多取一个。
转移方程为:dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j]);
这种情况下每个背包状态是不能从当前组继承的,即只能从上一组转移过来。所以初始化为上一组状态。
(3)s取2时,表示该组可以自由选择。
转移方程为:dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j], dp[flag][k-w[j]]+v[j]);(与s取0时相同。)
不过由于这种情况可以从当前组以及上一组继承,所以初始化为上一组状态。
最后结果还要和-1比较,取其大者。这是因为第一种情况初始值赋为INT_MIN的结果。
赋为INT_MIN的时候,如果该组的所有状态都取不到,那么结果肯定是会比-1小的。延续下去,最终结果也是比-1小,即这中状态是无法达到的。
【代码】
#include <iostream> using namespace std; const int maxn = 100; int dp[2][maxn+5]; int w[maxn+5], v[maxn+5]; inline int max(int a, int b, int c = INT_MIN) { if (a<b) a=b; if (a<c) a=c; return a; } int main() { int n, t, m, s, flag; int i, j, k; while(scanf("%d %d", &n, &t)!=EOF) { memset(dp, 0, sizeof(dp)); flag = 0; for (i=0; i<n; i++) { scanf("%d %d", &m, &s); for (j=0; j<m; j++) scanf("%d %d", &w[j], &v[j]); flag = 1 - flag; if (s==0)//at least { for (j=0; j<=t; j++) dp[flag][j] = INT_MIN; for (j=0; j<m; j++) { for (k=t; k>=w[j]; k--) { dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j], dp[flag][k-w[j]]+v[j]); } } } else if (s==1)//at most { for (j=0; j<=t; j++) dp[flag][j] = dp[1-flag][j]; for (j=0; j<m; j++) { for (k=t; k>=w[j]; k--) { dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j]); } } } else//freely { for (j=0; j<=t; j++) dp[flag][j] = dp[1-flag][j]; for (j=0; j<m; j++) { for (k=t; k>=w[j]; k--) { dp[flag][k] = max(dp[flag][k], dp[1-flag][k-w[j]]+v[j], dp[flag][k-w[j]]+v[j]); } } } } dp[flag][t] = max(dp[flag][t], -1); printf("%d\n", dp[flag][t]); } return 0; }
初始值赋为INT_MIN,则如果所有状态都取不到,结果就是INT_MIN,那么即使后面可以取到,这个值也是比-1小的,即这种状态是无法达到的。
相关文章推荐
- HDU3535 - AreYouBusy(混合背包+两种分组背包)
- hdu3535---AreYouBusy(混合分组背包,有坑点)
- hdu3535 (分组背包,最少选一 + 最多选一 + 随意)
- hdu3535 01&分组背包
- zoj 3164 Cookie Choice (分组混合背包)
- HDU 3535 分组混合背包
- dd大牛背包九讲(01,完全,多重,混合,二维,分组等背包)(转载+补充)一万二千字!!!
- HDU3535分组背包
- hdu3535 混合背包
- HDU3535AreYouBusy[混合背包 分组背包]
- 【背包问题】0-1背包、完全背包、多重背包、混合三种背包、二位费用背包、分组背包
- hdu 3535 经典混合分组背包
- HDU 3535 AreYouBusy(混合背包与分组背包)
- hdu 3535 分组背包+混合背包
- hdu 3535 AreYouBusy 混合背包
- hdu3535分组背包 必须选一次,最多选一次,不限制
- dp之分组背包hdu3535(推荐)
- hdu3535 分组背包的研究
- ZOJ 3164 Cookie Choice 分组背包 混合背包
- HDU 3535 AreYouBusy(混合背包+分组背包/至少取一件)