hdu3535(AreYouBusy)

题目链接:传送门

题目大意:有 n 组任务,m 个体力,每组任务有 k 个,分类为 f,每个任务花费 x 体力,得到 y 开心值,求最大开心值,若不能完成输出-1

     分类为 0:这一组中的 k 个任务至少选择一个。

     分类为 1:这一组中的 k 个任务最多选择一个。

     分类为 2:这一组中的 k 个任务随便选择。

     分析:

      1.对于分类 0,若当前判断到一个任务 x,则有两种情况:

        (1)它是该组第一个被选择的任务,则它更新的状态只能是将上一层的状态转移更新到当前位置。

        (2)它不是第一个被选择的任务,则它可以由当前组的状态转移更新到当前位置。

          为了方便判断处理第一个任务,初始化当前层为 -inf

      2.对于分类 1,因为只能选一个或者不选,则它只能由上一层状态转移更新。

      3.对于分类 2,就是普通的 01背包问题

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 1505
#define maxn 500005
typedef pair<int,int> PII;
typedef long long LL;
 
int dp[250][250];
int w[250],v[250];
int n,m,k,vv;
 
int main(){
    int i,j,group,id;
    while(scanf("%d%d",&n,&m)!=EOF){
        mst(dp,0);
        for(i=1;i<=n;++i){
            scanf("%d%d",&k,&vv);
            for(j=1;j<=k;++j) scanf("%d%d",&w[j],&v[j]);
            if(vv==0){  
                for(int l=0;l<=m;++l)dp[i][l]=INT_MIN+10000000;
                for(int l=1;l<=k;++l)
                for(int h=m;h>=w[l];--h){
                    dp[i][h]=max(dp[i][h],max(dp[i-1][h-w[l]],dp[i][h-w[l]])+v[l]);
                }
            }
            else if(vv==1){
                for(int l=0;l<=m;++l)dp[i][l]=dp[i-1][l];
                for(int l=1;l<=k;++l)
                for(int h=m;h>=w[l];--h)
                    dp[i][h]=max(dp[i][h],dp[i-1][h-w[l]]+v[l]);
            }
            else{
                for(int l=0;l<=m;++l)dp[i][l]=dp[i-1][l];
                for(int l=1;l<=k;++l)
                for(int h=m;h>=w[l];--h){
                    dp[i][h]=max(dp[i][h],dp[i][h-w[l]]+v[l]);
                }
            }
        }
        int temp=max(dp[n][m],-1);
        printf("%d\n",temp);
    }
    return 0;
}

 

posted @ 2016-08-10 15:47  Kurokey  阅读(261)  评论(0编辑  收藏  举报