P1417 烹调方案(01背包 + 排序)

题目连接:https://www.luogu.com.cn/problem/P1417

思路:

因为得到物品的价值与选取物品的先后顺序有关,假设有x,y两个物品,当前时刻为t

(1)先x后y,a[x] - (t + c[x])*b[x] + a[y] - (t + c[x] + c[y])*b[y];

(2)先y后x,a[y] - (t + c[y])*b[y] + a[x] - (t + c[y] + c[x])*b[x];

化简得到(1)>(2)的条件是 b[x] * c[y] > b[y] * c[x];

所以先按照上面的条件排序,然后01背包跑一遍就好了。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
struct Node{
    int a,b,c;
}cur[N];
long long dp[N] = {0};
int n,T;
bool cmp(Node a,Node b){
    return 1ll*a.b*b.c > 1ll*a.c*b.b;
}
int main(void)
{
    scanf("%d%d",&T,&n);
    for(int i=1;i<=n;i++) scanf("%d",&cur[i].a);
    for(int i=1;i<=n;i++) scanf("%d",&cur[i].b);
    for(int i=1;i<=n;i++) scanf("%d",&cur[i].c);
    sort(cur+1,cur+1+n,cmp);
    for(int i=1;i<=n;i++){
        for(int j=T;j>=cur[i].c;j--)
            dp[j] = max(dp[j],dp[ j - cur[i].c ] + 1ll*cur[i].a - 1ll*cur[i].b*j);
    }
    long long ans = dp[0];
    for(int i=1;i<=T;i++) ans = max(ans,dp[i]);
    printf("%lld\n",ans);
    return 0;
}
发布了438 篇原创文章 · 获赞 16 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/104074472