Problem B: 经营小卖部
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 28 Solved: 10
[ 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
背包。分四种情况讨论。什么都没有,有冰箱,有微波炉,既有冰箱又有微波炉。
每次取最大值。
注意dp数组要开大一点,尽管商品最多100个,但是状态不只有100个。否则会RE。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 1005
using namespace std;
typedef struct
{
int cost,value,type;
}Node;
Node a[N];
int dp[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int x,n,p1,p2;
scanf("%d%d%d%d",&x,&n,&p1,&p2);
for(int i=0;i<n;i++)
scanf("%d%d%d",&a[i].cost,&a[i].value,&a[i].type);
int ans=0;
memset(dp,0,sizeof(dp));
for(int i=1;i<=x;i++)
{
for(int j=0;j<n;j++)
if(i>=a[j].cost&&a[j].type==0)
dp[i]=max(dp[i],dp[i-a[j].cost]+a[j].value);
ans=max(ans,dp[i]-i);
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=x-p1;i++)
{
for(int j=0;j<n;j++)
if(i>=a[j].cost&&a[j].type!=2)
dp[i]=max(dp[i],dp[i-a[j].cost]+a[j].value);
ans=max(ans,dp[i]-i-p1);
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=x-p2;i++)
{
for(int j=0;j<n;j++)
if(i>=a[j].cost&&a[j].type!=1)
dp[i]=max(dp[i],dp[i-a[j].cost]+a[j].value);
ans=max(ans,dp[i]-i-p2);
}
memset(dp,0,sizeof(dp));
for(int i=1;i<=x-p1-p2;i++)
{
for(int j=0;j<n;j++)
if(i>=a[j].cost)
dp[i]=max(dp[i],dp[i-a[j].cost]+a[j].value);
ans=max(ans,dp[i]-i-p1-p2);
}
printf("%d\n",ans);
}
return 0;
}