題目描述
王老師 最近搬家了,需要購置 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++){
if(
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++){
if(