HDU 3033 I love sneakers!
题目
http://acm.hdu.edu.cn/showproblem.php?pid=3033
有K种运动鞋,N个鞋子(每个鞋最多只能买一次),总钱数为M,求不超过总钱数且每种鞋子至少买一双情况下的最大总价值。如果买不到所有种,就输出“Impossible”。
这个题的关键还是在于初始化,如果我们一开始把dp初始化为0,则当所有鞋子的价值都是0时,我们就无法区分是买不全那几款鞋子还是能买全但最大价值是0;因此,要把S!=0的dp[S][j]初始化为-1,便于区分。
输入输出
输入:
N(鞋个数)M(总钱数)K(鞋的种类数)
a(鞋种类号)b(鞋的价格)c(鞋的价值(得分))
多组数据
输出:
能获得的最大鞋的总价值
多组数据
思路
分组背包,外层循环组数。内层为01背包,两重循环。
dp[i][j]:第i种鞋子有j钱数能获取的最大鞋的总价值(不装满的情况)。
状态转移公式:dp[i][j]=max(dp[i][j],dp[i-1][j-price[i][l]]+value[i][l],dp[i][j-price[i][l]]+value[i][l])
当i=0时,dp[i][j]=0,当i!=0时,dp[i][j]=-100000(初始化第0组最大价值为0,其他组为-100000,因为b<100000)
注~
1.当i!=0时,dp为一个负数,则每一组对应dp必须有选取物品,即由其前面的组叠加来才不为负数。判断负数。
#pragma comment(linker,"/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<iomanip>
#include<algorithm>
#include<numeric>
#include<functional>
#include<memory>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<fstream>
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
const double pi=acos(-1.0);
const int INF=0x3f3f3f3f;
const int MAX=0x7fffffff;
const long long LINF=0x3f3f3f3f3f3f3f3f;
const long long LMAX=0x7fffffffffffffff;
const double eps=1e-9;
const int Mod=100007;
const int Max=10000005;
using namespace std;
int N,M,K;
vector<int> price[102];
vector<int> value[102];
int dp[12][10002];
int max3(int a,int b,int c){
return (a)>(b)?((a)>(c)?(a):(c)):((b)>(c)?(b):(c));
}
int main() {
freopen("data.in","r",stdin);
cin.sync_with_stdio(false);
cout.sync_with_stdio(false);
while(cin>>N>>M>>K){
memset(dp,0,sizeof(dp));
for(int i=0;i<=K;++i){
for(int j=0;j<=M;++j){
if(i==0){
dp[i][j]=0;
}else{
dp[i][j]=-100000;
}
}
}
for(int i=1;i<=K;++i){
price[i].clear();
value[i].clear();
}
int id,p,v;
for(int i=0;i<N;++i){
cin>>id>>p>>v;
price[id].push_back(p);
value[id].push_back(v);
}
for(int j=1;j<=K;++j){
for(int l=0;l<price[j].size();++l){
for(int i=M;i>=price[j][l];--i){
//cout<<"dp["<<j<<"]["<<i<<"]=max("<<"dp["<<j<<"]["<<i<<"]="<<dp[j][i]<<' '<<dp[j-1][i-price[j][l]]+value[j][l]<<' '<<dp[j][i-price[j][l]]+value[j][l]<<")"<<endl;
if(dp[j-1][i-price[j][l]]>=0||dp[j][i-price[j][l]]>=0)
dp[j][i]=max3(dp[j][i],dp[j-1][i-price[j][l]]+value[j][l],dp[j][i-price[j][l]]+value[j][l]);
}
}
}
if(dp[K][M]>=0)
cout<<dp[K][M]<<endl;
else
cout<<"Impossible"<<endl;
}
fclose(stdin);
return 0;
}