1671: 经营小卖部
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 29 Solved: 11
[ Submit][ Status][ Web Board]
Description
暑假很多店都关门了,还坚持营业的店可以收揽大多数客户。看准了这个商机,你和小伙伴们打算集资开一个小卖部。
你们总共集资了X元,可以用来购置商品和其他配置。每个商品有自己的进价和售价,你可以根据自己的要求以进价购入任意数量的商品,并全部以售价卖出。但是部分商品要求小卖部要有对应设施,比如冰淇淋和饮料要求有冰箱,粽子和方便面要求有微波炉。那么,如何才能得到最大利润?
Input
多组数据,第一行有一个整数
T
,表示有
T
组数据。
(
T<=100
)
以下每组数据
第一行
有
四
个整数
X,N,P1
和
P2。X是你们的资金总数
(1<=
X
<=
1000
)
。N
表示
商品种类数
(1<=
N
<=
100
)
,P1和P2分别
表示
冰箱和微波炉的价格
(1<=
P1,P2
<=
1000
)
。之后N行每行三个整数,C1,C2(
1<=
C1,C2
<=
1000)和A,分别表示这个商品的进价、售价和对设备的要求(A为0表示无需求,A为1表示需要冰箱,A为2表示需要微波炉)。
Output
一个整数,表示最大的利润。
Sample Input
2
10 3 1 1
1 2 0
1 3 1
2 4 2
10 3 1 1
5 6 0
3 5 1
5 11 2
Sample Output
17
6
HINT
Source
背包dp,做4次就好了
分四种情况买与不买冰箱,买与不买微波炉
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int M=1005;
int dp[M];
struct NODE
{
int c1,c2,a;
}good[M];
int main()
{
int t;
int x,n,p1,p2;
int ans;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d",&x,&n,&p1,&p2);
ans=0;
for(int i=1;i<=n;i++)
scanf("%d%d%d",&good[i].c1,&good[i].c2,&good[i].a);
for(int i=1;i<=n;i++)
{
good[i].c2=good[i].c2-good[i].c1;
}
memset(dp,0,sizeof(dp));
for(int i=0;i<=x;i++)
{
for(int j=1;j<=n;j++)
if(!good[j].a&&i>=good[j].c1)
dp[i]=max(dp[i],dp[i-good[j].c1]+good[j].c2);
ans=max(ans,dp[i]);
}
if(x-p1>0)
{
memset(dp,0,sizeof(dp));
for(int i=0;i<=x-p1;i++)
{
for(int j=1;j<=n;j++)
if(good[j].a!=2&&i>=good[j].c1)
dp[i]=max(dp[i],dp[i-good[j].c1]+good[j].c2);
ans=max(ans,dp[i]-p1);
}
}
if(x-p2>0)
{
memset(dp,0,sizeof(dp));
for(int i=0;i<=x-p2;i++)
{
for(int j=1;j<=n;j++)
if(good[j].a!=1&&i>=good[j].c1)
dp[i]=max(dp[i],dp[i-good[j].c1]+good[j].c2);
ans=max(ans,dp[i]-p2);
}
}
if(x-p1-p2>0)
{
memset(dp,0,sizeof(dp));
for(int i=0;i<=x-p1-p2;i++)
{
for(int j=1;j<=n;j++)
if(i>=good[j].c1)
dp[i]=max(dp[i],dp[i-good[j].c1]+good[j].c2);
ans=max(ans,dp[i]-p1-p2);
}
}
printf("%d\n",ans);
}
return 0;
}