Solution

经典0-1背包问题, 题目的输入描述有点问题

第3-n+2行 -> 第 3 - m + 2 行

直接做背包是错的, 因为这里多了一个时间的限制, 价值随着时间而变化
同样是背包但是先进背包和后进背包有区别
因此需要考虑贪心策略下背包
对于两个物体 , , 先取 物体比先取 物体优
当且仅当
化简一下就是
排序后进行背包就行了
注意题目要求必须至少做一道菜, 这里有个人尽皆知的小技巧
数组赋值为无穷小, , 这样可以保证 满足至少取一个

Code

/*
  autor: Kurisu
  2020年4月30日08:59:23
*/
#include<bits/stdc++.h>
using namespace std;

const long long inf = 1e18;
const int N = 2e5 + 5;
const double eps = 1e-10;
const int mod = 1e9 + 7;
typedef long long ll;
ll b[N];
ll dp[N];
struct node {
  ll id, a, c;
  bool operator < (const node &s) const {
    return b[s.id] * c < b[id] * s.c;
  }
}d[N];
int main() {
  int n, m, t;
  cin >> n >> m >> t;
  for(int i = 1; i <= n; i++) cin >> b[i];
  for(int i = 1; i <= m; i++) {
    cin >> d[i].id >> d[i].a >> d[i].c;
  } 
  sort(d + 1, d + 1 + m);
  memset(dp, -0x3f, sizeof(dp));
  dp[0] = 0;
  ll ans = -1e18;
  for(int i = 1; i <= m; i++) {
    for(int j = t; j >= d[i].c; j--) {
      dp[j] = max(dp[j], dp[j - d[i].c] + d[i].a - b[d[i].id] * j);
      ans = max(ans, dp[j]);
    }
  }
  cout << ans << "\n";
  return 0;
}