HDU - 3535 areyoubusy (Group pack)

Title:

Given several groups of backpacks, each group has a corresponding type, (take at least one, take at most, take arbitrarily), each item can only be taken once, and calculate the maximum value that meets the conditions.

Analysis:

As long as I remind myself to remember the three ways of writing backpacks, I really understand them,

Note that at least one and two judgment conditions can not be interchanged, because there may be a situation of 0, so the exchange may cause an item to be taken twice.

It can't be written at most onceBecause maybe the maximum dp[x][v] of that item has been calculated before, but it is not considered in the next calculation.

#include<bits/stdc++.h>

using namespace std;

const int maxn=105;

int n,T,m;

struct node{
    int c,g;
    node(int c,int g):c(c),g(g){}
    node(){}
};

vector<node> p[maxn];
int s[maxn];

int dp[maxn][maxn];

void least(int x){
    for(int i=0;i<p[x].size();i++){
        for(int v=T;v>=p[x][i].c;v--){
            if(dp[x][v-p[x][i].c]!=-1){
                dp[x][v]=max(dp[x][v],dp[x][v-p[x][i].c]+p[x][i].g);
            }
            if(dp[x-1][v-p[x][i].c]!=-1){
                dp[x][v]=max(dp[x][v],dp[x-1][v-p[x][i].c]+p[x][i].g);
            }
        }
    }
}

void most(int x){
    for(int i=0;i<=T;i++){
        dp[x][i]=dp[x-1][i];
    }
    for(int i=0;i<p[x].size();i++){
        for(int v=T;v>=p[x][i].c;v--){
            if(dp[x-1][v-p[x][i].c]!=-1)
                dp[x][v]=max(dp[x][v],dp[x-1][v-p[x][i].c]+p[x][i].g);
        }
    }
}

void free(int x){
    for(int i=0;i<=T;i++){
        dp[x][i]=dp[x-1][i];
    }
    for(int i=0;i<p[x].size();i++){
        for(int v=T;v>=p[x][i].c;v--){
            if(dp[x][v-p[x][i].c]!=-1)
                dp[x][v]=max(dp[x][v],dp[x][v-p[x][i].c]+p[x][i].g);
        }
    }
}

int main(){
    while(scanf("%d%d",&n,&T)!=EOF){
        for(int i=1;i<=n;i++){
            p[i].clear();
        }
        for(int i=1;i<=n;i++){
            scanf("%d%d",&m,&s[i]);
            for(int j=1;j<=m;j++){
                int c,g;
                scanf("%d%d",&c,&g);
                p[i].push_back(node(c,g));
            }
        }
        memset(dp,-1,sizeof dp);
        for(int i=0;i<=T;i++){
            dp[0][i]=0;
        }
        for(int i=1;i<=n;i++){
            if(s[i]==0){
                least(i);
            }else if(s[i]==1){
                most(i);
            }else free(i);
        }
        printf("%d\n",dp[n][T]);
    }
    return 0;
}

 

Posted by wintallo on Wed, 27 Nov 2019 09:29:44 -0800