【洛谷P1417】烹調方案 貪心+背包dp
阿新 • • 發佈:2019-05-09
void urn 設計 pri n) clu can 產生 space
題目大意:一共有 n 件食材,每件食材有三個屬性,ai,bi和ci,如果在t時刻完成第i樣食材則得到ai-t*bi的美味指數,用第i件食材做飯要花去ci的時間。眾所周知,gw的廚藝不怎麽樣,所以他需要你設計烹調方案使得美味指數最大。
題解:這道題需要對背包問題有更加深入的理解。
可以發現,如果不進行排序操作的話,先選的物品會對後續選擇的物品的價值產生影響,即:答案與選擇的先後順序有關。這與 0-1 背包問題不同,對於 0-1 背包問題來說,先選擇的物品對後續物品答案的貢獻沒有影響,因此與選擇的順序無關。對於這種物品之間價值會相互影響的情況,首先考慮固定一個子集,對集合內的元素按某種順序排序,擴展到整個集合來說,即:先進行排序,再進行 dp 即可。
代碼如下
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=55; const int maxx=1e5+10; int T,n; LL dp[maxx]; struct node{int a,b,c;}t[maxn]; bool cmp(const node &x,const node &y){ return (LL)x.c*y.b<(LL)x.b*y.c; } void read_and_parse(){ scanf("%d%d",&T,&n); for(int i=1;i<=n;i++)scanf("%d",&t[i].a); for(int i=1;i<=n;i++)scanf("%d",&t[i].b); for(int i=1;i<=n;i++)scanf("%d",&t[i].c); sort(t+1,t+n+1,cmp); } void solve(){ for(int i=1;i<=n;i++) for(int j=T;j>=t[i].c;j--) dp[j]=max(dp[j],dp[j-t[i].c]+t[i].a-(LL)t[i].b*j); LL ans=0; for(int i=0;i<=T;i++)ans=max(ans,dp[i]); printf("%lld\n",ans); } int main(){ read_and_parse(); solve(); return 0; }
【洛谷P1417】烹調方案 貪心+背包dp