新赛道-2024.8 CSP-J组月赛-T4
题目描述
王老师 最近搬家了,需要购置 a 台家电、b 件家具和 c 个装饰。他来到了商场,商场正好在举行优惠大酬宾,每家店铺都推出了一系列活动。
一共有 n=a+b+c 家店铺,活动期间在第 i 家店铺购买家电只需要 ai 元一台,购买家具只需要 bi 元一件,购买装饰只需要 ci 元一个,但每一家店铺限定每位顾客最多只能购买一种类型的物品一个。
王老师 希望在满足采购需求的情况下总花费最少,你能帮帮他求出最小花费吗?
数据范围
对于所有数据 n,a,b,c≤5000,ai,bi,ci≤109 ,保证 n=a+b+c 。
测试点 | 数据范围 |
---|---|
1∼4 | n≤15 |
5∼10 | n≤100 |
11∼14 | c=0 |
15∼20 | 无限制 |
首先根据题面不难想到定义dp[i][j][k](表示经过i家店铺,买j台家电,k件家具,n-j-k个装饰的最小花费),但只能过%50分。
考虑优化:我们可以利用贪心来优化dp[i][j]表示考虑了1到i家店,选了j个装饰的最小费用,那么剩下i-j个物品就会按照贪心策略优先买购买家具,然后购买家电。
按b[i]-a[i]排序,便有以下转移方程
若i-j<=B f[i][j]=min(f[i-1][j-1]+c[i],f[i-1][j]+b[i])
否则:f[i][j]=min(f[i-1][j-1]+c[i],f[i-1][j]+a[i]);
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
int f[5005][5005],n,a,b,c;
struct node{
int a,b,c;
}s[5005];
bool cmp(node x,node y){
return x.b-x.a<y.b-y.a;
}
signed main(){
freopen("buy.in","r",stdin);
freopen("buy.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>a>>b>>c;
for(int i=1;i<=n;i++)cin>>s[i].a>>s[i].b>>s[i].c;
sort(s+1,s+n+1,cmp);
memset(f,0x3f,sizeof(f));
f[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=min(i,c);j++){
using namespace std;
#define int long long
int f[5005][5005],n,a,b,c;
struct node{
int a,b,c;
}s[5005];
bool cmp(node x,node y){
return x.b-x.a<y.b-y.a;
}
signed main(){
freopen("buy.in","r",stdin);
freopen("buy.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>a>>b>>c;
for(int i=1;i<=n;i++)cin>>s[i].a>>s[i].b>>s[i].c;
sort(s+1,s+n+1,cmp);
memset(f,0x3f,sizeof(f));
f[0][0]=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=min(i,c);j++){