这是一个完全背包问题,要分四种情况讨论:1.什么工具都不买 2.买微波炉 3.买冰箱 4.买微波炉 和 冰箱 。然后取其中利润最大的一种
状态 dp[j] : 所给资金为j时的最大营业额。
转移方程: dp[j]=max{dp[j],dp[j-ci]+wi} //这里的wi指的是单个物品的利润。
以下为代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct snode
{
int c,w,A;
}a[123];
int dp[1234];
int main()
{
// freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--){
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
int X,n,p1,p2;
int maxx=0;
scanf("%d%d%d%d",&X,&n,&p1,&p2);
for(int i=0;i<n;i++)
scanf("%d%d%d",&a[i].c,&a[i].w,&a[i].A);
for(int i=0;i<n;i++){
if(a[i].A!=0)continue; //什么工具都不买。
for(int j=a[i].c;j<=X;j++)
dp[j]=max(dp[j],dp[j-a[i].c]+a[i].w-a[i].c);
}
maxx=max(maxx,dp[X]);
if(X-p1>0){ //买冰箱
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++){
if(a[i].A==2)continue;
for(int j=a[i].c;j<=X-p1;j++) //这里相当于把买工具的钱先扣除了。
dp[j]=max(dp[j],dp[j-a[i].c]+a[i].w-a[i].c);
}
maxx=max(maxx,dp[X-p1]-p1); //注意利润是dp[X-p1]-p1; 因为最开始买工具的钱要算在成本里
}
if(X-p2>0){ //买微波炉
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++){
if(a[i].A==1)continue;
for(int j=a[i].c;j<=X-p2;j++)
dp[j]=max(dp[j],dp[j-a[i].c]+a[i].w-a[i].c);
}
maxx=max(maxx,dp[X-p2]-p2);
}
if(X-p1-p2>0){//两种工具都买
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++){
for(int j=a[i].c;j<=X-p2-p1;j++)
dp[j]=max(dp[j],dp[j-a[i].c]+a[i].w-a[i].c);
}
maxx=max(maxx,dp[X-p1-p2]-p1-p2);
}
printf("%d\n",maxx);
}
return 0;
}