洛谷 1417 烹調方案
咱麽來看看這道題
題目背景
由於你的幫助,火星只遭受了最小的損失。但gw懶得重建家園了,就造了一艘飛船飛向遙遠的earth星。不過飛船飛到一半,gw發現了一個很嚴重的問題:肚子餓了~
gw還是會做飯的,於是拿出了儲藏的食物準備填飽肚子。gw希望能在T時間內做出最美味的食物,但是這些食物美味程度的計算方式比較奇葩,於是絕望的gw只好求助於你了。
題目描述
一共有n件食材,每件食材有三個屬性,ai,bi和ci,如果在t時刻完成第i樣食材則得到ai-t*bi的美味指數,用第i件食材做飯要花去ci的時間。
眾所周知,gw的廚藝不怎麽樣,所以他需要你設計烹調方案使得美味指數最大
輸入輸出格式
輸入格式:
第一行是兩個正整數T和n,表示到達地球所需時間和食材個數。
下面一行n個整數,ai
下面一行n個整數,bi
下面一行n個整數,ci
輸出格式:
輸出最大美味指數
【數據範圍】
對於40%的數據1<=n<=10
對於100%的數據1<=n<=50
所有數字均小於100,000
題意:我就不解釋了,很好懂
乍一看,這不是01背包嗎?哇這麽水的嗎?
仔細一看emmmmm,好像有點不一樣,這裏的價值是隨時間變化而變化的
嗯,好像有點難
咱們來想一下,考慮一下相鄰取的兩個物品x,y的價值
假設現在已經花費的時間為t,這兩個物品分別為x,y
v1=d[x].a-(t+d[x].c)*d[x].b+d[y].a-(t+d[x].c+d[y].c)*d[y].b
v2=d[y].a-(t+d[y].c)*d[y].b+d[x].a-(t+d[y].c+d[x].c)*d[x].b
要是v1>v2
則v1-v2可得
d[x].b*d[y].c>d[y].b*d[x].c
我們可以的出來
一個物品的價值是d[i].c/d[i].b
只要取的順序x比y小則它的價值更優
我們可以按照這個來排序
排完序之後
就是簡單的01背包了
上代碼
#include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include<cstring> using namespace std; typedef long long ll; const int N=500005; struct node { ll a,b,c; }d[100]; ll n,t,dp[N]; bool cmp(node x,node y) { return x.c*y.b<y.c*x.b; } int main() { scanf("%lld %lld",&t,&n); for(ll i=1;i<=n;i++) scanf("%lld",&d[i].a); for(ll i=1;i<=n;i++) scanf("%lld",&d[i].b); for(ll i=1;i<=n;i++) scanf("%lld",&d[i].c); sort(d+1,d+n+1,cmp); for(ll i=1;i<=n;i++) for(ll j=t;j>=d[i].c;j--) { dp[j]=max(dp[j],dp[j-d[i].c]+d[i].a-j*d[i].b); } ll ans=0; for(ll i=0;i<=t;i++) ans=max(dp[i],ans); printf("%lld\n",ans); return 0; }
解決了
洛谷 1417 烹調方案