HDU 3033 I love sneakers! -- 分组背包 每组最少拿一个

来源:互联网 发布:当代网络三大奇书 编辑:程序博客网 时间:2024/06/06 02:27
/*    http://acm.hdu.edu.cn/showproblem.php?pid=3033  I love sneakers!分组背包 每组最少拿一个 注意初始化 和 每组物品必须同时处理*/#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 M   =  1e4 + 10;const int CASE = 10 + 2;int dp[CASE][M];    // dp[i][0]初始化为0 其中i:(0->10), 其余为infint v[CASE][M];int c[CASE][M];int main(){//freopen("in.txt","r",stdin);int n_case, max_cost, n_set;while(cin >> n_case >> max_cost >> n_set){CLR(dp,0);for(int j = 0 ; j <= max_cost ; j++){dp[0][j] = 0;}for (int i = 1 ; i <= n_set ; i++){for(int j = 0 ; j <= max_cost ; j++){dp[i][j] = inf; // 初始化 确保每个集合中 至少哪一个物品}}int brand,cnt[CASE];CLR(cnt,0);for (int i = 1 ; i <= n_case ; i++,cnt[brand]++){ // 每一个集合的背包 必须同时处理cin >> brand ;cin >> c[brand][cnt[brand]] >> v[brand][cnt[brand]];}for (int i = 1 ; i <= n_set ; i++){ //每一个类型的物品集合,每个集合最少放一个for (int j = 0 ; j < cnt[i] ; j++){ // 遍历每个集合中的所有物品for(int k = max_cost ; k >= c[i][j] ; k--){ dp[i][k] = Max(dp[i][k], dp[i-1][k-c[i][j]]+v[i][j], dp[i][k-c[i][j]]+v[i][j]);}}}if (dp[n_set][max_cost] < 0)cout << "Impossible" << endl;elsecout << dp[n_set][max_cost] << endl;}return 0;}

原创粉丝点击