HDU - 3033 I love sneakers! (分组背包)

题意

有n件物品,每个物品属于特定的品牌,且价格和收益两个属性.每个品牌最多买1个东西,求最大收益.

分析

\(dp[i][j]\) 枚举前i个品牌,话费为j的最大收益.则分组背包有状态转移:

\[dp[i][j] = max(dp[i][j], max(dp[i][j-w]+v,dp[i-1][j-w]+v)) \]

因为要判断无解的情况,所以将dp[i][j]初始成-1,最后检查dp[k][m]是否被修改.

#include<bits/stdc++.h>
#define PII pair<int,int>
#define MP make_pair
#define X first
#define Y second
using namespace std;
const int maxn = 1e4+5;
typedef long long LL;
int dp[105][maxn];
vector<pair<int,int> > vz[15];


int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    #endif
    int n,m,k;
    while(scanf("%d %d %d",&n, &m, &k)==3){
        memset(dp,-1,sizeof(dp));
        memset(dp[0],0,sizeof(dp[0]));

        for(int i=0;i<15;++i) vz[i].clear();

        for(int i=1,a,b,c;i<=n;++i){
            scanf("%d %d %d",&a, &b, &c);
            vz[a].push_back(MP(b,c));
        }

        for(int t=1;t<=k;++t){
            for(int i=0;i<vz[t].size();++i){
                int w = vz[t][i].X;
                for(int j=m;j>=w;--j){
                    int v = vz[t][i].Y;
                    if(dp[t][j-w]!=-1)
                        dp[t][j] = max(dp[t][j],dp[t][j-w]+v);
                    if(dp[t-1][j-w]!=-1){
                        dp[t][j] = max(dp[t][j],dp[t-1][j-w]+v);
                    }
                }
            }
        }

        if(dp[k][m]==-1) printf("Impossible\n");
        else printf("%d\n",dp[k][m]);
    }
    return 0;
}

posted @ 2018-10-22 21:08  xiuwenL  阅读(172)  评论(0编辑  收藏  举报