您的位置:首页 > 其它

I love sneakers! hdu 3033 分组背包

2014-11-28 16:32 351 查看
至少选一项,即必须要选,那么在开始时,对于这一组的dp的初值,应该全部赋为负无穷,这样才能保证不会出现都不选的情况。状态转移方程为dp[i][k]=max{ dp[i][k],dp[i-1][k-cost[j]]+val[j],dp[i][k-cost[j]]+val[j] }。dp[i][k]是不选择当前工作;dp[i-1][k-cost[j]]+val[k]是选择当前工作,但是是第一次在本组中选,由于开始将该组dp赋为了负无穷,所以第一次取时,必须由上一组的结果推知,这样才能保证得到全局最优解;dp[i][k-cost[j]]+val[j]表示选择当前工作,并且不是第一次取。

/********************
 * Author:fisty
 * DATA:2014-11-28
 * hdu3033
 * 分组背包
 * ******************/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

#define MAX_N 10100
#define INF 0x3f3f3f3f
int n, m, k;
int dp[MAX_N][MAX_N];
struct edge{
        int c;
        int v;
        edge(int _c, int _v): c(_c), v(_v){}  
};
int main(){
        while(scanf("%d%d%d", &n, &m, &k) != EOF){
                vector<edge> bag[MAX_N];
                for(int i = 0;i < n; i++){
                        int t,c, v;
                        scanf("%d%d%d", &t, &c, &v);
                        bag[t].push_back(edge(c, v));
                }
                for(int i = 1;i <= k; i++){
                        for(int j = 0;j <= m; j++)
                                dp[i][j] = -INF;
                        for(int j = 0;j < bag[i].size(); j++){
                                for(int w = m; w >= bag[i][j].c; w--){
                                        dp[i][w] = max(dp[i][w], dp[i][w-bag[i][j].c] + bag[i][j].v);
                                        dp[i][w] = max(dp[i][w], dp[i-1][w-bag[i][j].c] + bag[i][j].v);
                                }
                        }
                }
                if(dp[k][m] != -INF) 
                        printf("%d\n", dp[k][m]);
                else
                        printf("Impossible\n");

        }
        return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: