【每日一题】美味佳肴 4.27
美味菜肴
https://ac.nowcoder.com/acm/problem/14704
01背包问题
但并不是简单的01背包问题,因为与选取的顺序有关,观察公式A[i]-t*B[i],对任意两道菜先选哪道菜结果肯定最大呢?
化简一下公式就可以知道,只有末尾一项不一样,那么按末尾那项降序排列即可
然后就是01背包问题了,重量是c,价值是a[i]-b[i]*t(t是做完这道菜的时间),背包容量是T,即可得到答案了
最后记得开long long
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e6+7;
const int inf = 0x3f3f3f3f;
ll dp[maxn],f[55];
struct node{
ll a,b,c;
bool operator < (const node& x)const
{
return c*x.b<x.c*b;
}
}p[55];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);
int n,m,T;
cin>>n>>m>>T;
for(int i=1;i<=n;i++) cin>>f[i];
for(int i=1;i<=m;i++)
{
cin>>p[i].b>>p[i].a>>p[i].c;
p[i].b = f[p[i].b];
}
sort(p+1,p+1+m);
memset(dp,-inf,sizeof(dp));dp[0] = 0;
//01背包
for(int i=1;i<=m;i++)
for(int j=T;j>=p[i].c;j--)
{
dp[j] = max(dp[j],dp[j-p[i].c]+p[i].a-j*p[i].b);
}
ll ans = -inf;
for(int i=1;i<=T;i++) ans = max(ans,dp[i]);
cout<<ans;
return 0;
}

查看1道真题和解析