/*
http://acm.hdu.edu.cn/showproblem.php?pid=1712 ACboy needs your helpss
分组背包 每组最多拿一个 ,一定要注意初始化,当前需要循环的初始化为上一次的结果,才能保证全局最优解
这题目卡cin,数据太多了,让我超时了一次
另外这题目还有一个办法,改变循环顺序也可使得每组至多拿一个物品
*/
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#define CLR(c,v) (memset(c,v,sizeof(c)))
using namespace std;
template <typename _T>
inline _T Max(_T a,_T b){
return (a>b)?(a):(b);
}
template <typename _T>
inline _T Max(_T a,_T b,_T c){
return (a>Max(b,c))?(a):(Max(b,c));
}
const int inf = -(1<<30);
const int INF = (1<<30);
const int SET = 100 + 2;
const int COST = 1e2 + 2; // 一消耗 时间限制
int dp[SET][COST];
int main(){
freopen("Input.txt","r",stdin);
freopen("out.txt","w",stdout);
int n_set, max_cost;
while(cin >> n_set >> max_cost && (n_set || max_cost)){
CLR(dp,0);
for (int i = 1 ; i <= n_set ; i++){ // foreach set
for (int t = 0 ; t <= max_cost ; t++)
dp[i][t] = dp[i-1][t]; // 为了保证全局最优解,初始化为上一次结果
for (int j = 1 ; j <= max_cost ; j++){// foreach cost1
int value;
scanf("%d",&value);
int c1 = j;
int c2 = 1;
for (int t = max_cost ; t >= c1 ; t--){ // foreach cost1
dp[i][t] = Max(dp[i][t], dp[i-1][t-c1] + value);
// 这种循环不是由二维费用演变过来的,
// 当这里改成二维费用的话则表示全局仅拿一个的情况,
// 必须将初始化修改为拿0个的为上一次拿一个的最优值才行
// 而是每次 当前值 仅跟 最初始状态+now_value比较,取最大值
}
}
}
cout << dp[n_set][max_cost] << endl;
}
return 0;
}
HDU 1712 ACboy needs your helpss - 分组背包+最多那一个
最新推荐文章于 2013-10-12 09:57:48 发布