每日一题(美味佳肴)

美味菜肴

https://ac.nowcoder.com/acm/problem/14704

首先我们发现如果交换两个菜肴做的顺序,sum(ai)是不变的,也就是只剩下两个变量。此时容易想到可以通过代数运算得到做菜顺序。其实贪心思路也挺显然的,肯定是让减少的少的先做,并且同时和做这道菜的时间有关,所以我们此时通过代数运算得到当a.c/a.b < b.c/b.c的时候,先做a是优于先做b的。 然后就是一个标标准准的01背包。

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
mt19937 mrand(random_device{}()); 
const ll mod=998244353;
int rnd(int x) { return mrand() % x;}
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}


const int N = 2e6 + 50;
ll n, m, T;
struct node {
    ll a, b, c;
}a[N];
bool cmp(const node &x, const node &y) {
    return x.c * y.b < y.c * x.b;
}
ll p[N], dp[N];
int main()
{
    cin >> n >> m >> T;
    for(int i = 1; i <= n; i ++){
        cin >> p[i];
    }
    for(int i = 1; i <= m; i ++){
        ll q; 
        cin >> q >> a[i].a >> a[i].c;
        a[i].b = p[q];
    }
    memset(dp ,-0x3f, sizeof dp);
    dp[0] = 0;
    sort(a + 1, a + 1 + m, cmp);
    for (int i = 1; i <= m; i ++){
        for (int j = T; j >= a[i].c; j --){
            dp[j] = max(dp[j], dp[j - a[i].c] + a[i].a - j * a[i].b);
        }
    }
    ll res = -1e9;
    for (int i = 1; i <= T; i ++) res = max(res, dp[i]);
    cout << res;
    return 0;
}
全部评论

相关推荐

大叔叔1:你把自己说的话打码,所以你想表达什么
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务