题意
有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
");
else printf("%d
",dp[k][m]);
}
return 0;
}