题意:有n种食材,m种菜肴,每种菜肴给出所需食材和美味值和制作时间,因为每种食材以a[i]的速率变得不新鲜,求在t秒总美味值最大为多少?
注意:最大总美味值可能为负。
思路:贪心+01背包
贪心:
设二种相邻菜肴,第一种所需食材变的不新鲜的速率为w[i].a,美味值为w[i].b,制作时间为w[i].c,第二种所需食材变的不新鲜的速率为w[i+1].a,美味值为w[i+1].b,制作时间为w[i+1].c;
如果顺序正确则需满足:
w[i].b-w[i].aw[i].c+w[i+1].b-(w[i].c+w[i+1].c)w[i+1].a
<w[i+1].b-w[i+1].aw[i+1].c+w[i].b-(w[i].c+w[i+1].c)w[i].a
化简为:w[i+1].cw[i].a>w[i].cw[i+1].a
01dp:
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i].c]+w[i].b-w[i].a*j);
代码:
#include<bits/stdc++.h> #define inf 1000000007 using namespace std; typedef long long ll; struct w { ll a, b, c; }w[105]; int a[105]; ll dp[1000005]; bool cmp(struct w a,struct w b) { return a.a*b.c>b.a*a.c; } int main() { int n, m, t; scanf("%d %d %d",&n,&m,&t); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } for(int i=1;i<=m;i++) { scanf("%lld %lld %lld",&w[i].a,&w[i].b,&w[i].c); w[i].a=a[w[i].a]; } sort(w+1,w+m+1,cmp); fill(dp,dp+1000005,-100000007); dp[0]=0; for(int i=1;i<=m;i++) { for(int j=t;j>=0;j--) { if(j>=w[i].c) dp[j]=max(dp[j],dp[j-w[i].c]+w[i].b-w[i].a*j); } } ll ma=-10000000007; for(int i=1;i<=t;i++) { ma=max(ma,dp[i]); } printf("%lld\n",ma); return 0; }