题目大意:小明有在商场碰上了促销,小明刚好是会员,会员可以利用money,积分,免费拿k件的方式买衣服.小明看上了商场上的n件物品,并对它们标出了相应的花费,以及价值.求小明最多能买价值多少的衣服.
思路:多维DP.01背包扩展一下就可以了,麻烦的是有一点在状态转移方程
我用四维写的,其实三维更省空间,这里懒惰了.
Dp[i][j][k][g]=max(Dp[i-1][j][k][g],Dp[i][j-cost[i]][k][g]+val[i],Dp[i][j][k-fen[i]][g]+val[i]),
Dp[i][j][k][g-1]+val[i]))
Dp[i][j][k][g]表示:用j钱k积分g免费拿的机会 买了i件物品获得的最大价值
AC program:
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <queue>
#include <cassert>
typedef long long ll;
#define rep(i,a,b) for(int i=(a);i<(int)(b);i++)
#define per(i,a,b) for(int i=((a)-1);i>=(int)(b);i--)
#define clr(a) memset((a),0,sizeof (a))
#define inf (0x7fffffff)
#define eps 1e-6
#define MAXN
#define MODN (1000000007)
/*
x = x^y;
y = x^y;
x = x^y;
*/
using namespace std;
using namespace std;
int dp[101][101][101][6];
int cost[101],fen[101],val[101];
int main(){
int test;
int n,v1,v2,free;
while(cin>>n>>v1>>v2>>free){
rep(i,1,n+1){
cin>>cost[i]>>fen[i]>>val[i];
}
clr(dp);
rep(i,1,n+1){
rep(j,0,v1+1){
rep(k,0,v2+1){
rep(g,0,free+1){
//dp[i][j][k][g]=max(dp[i-1][j][k][g],dp[i][j][k][g]);
//分组背包与多维背包的区别在哪...
int tmp=dp[i-1][j][k][g];
if(cost[i]<=j){
tmp=max(tmp,dp[i-1][j-cost[i]][k][g]+val[i]);
}
if(fen[i]<=k){
tmp=max(tmp,dp[i-1][j][k-fen[i]][g]+val[i]);
}
if(g>=1){
tmp=max(tmp,dp[i-1][j][k][g-1]+val[i]);//dp[i-1]写成dp[i]的悲剧史了
}
dp[i][j][k][g]=max(tmp,dp[i][j][k][g]);
}
}
}
}
cout<<dp[n][v1][v2][free]<<endl;
};
//system("pause");
return 0;
}