[关闭]
@yuyuesheng 2019-02-26T16:04:00.000000Z 字数 1467 阅读 719

I - Lunar New Year and Red Envelopes

题意:
在长度为n的时间轴上,有k个红包,每个红包有领取时间段[s,t],价值w,以及领了个这个红包之后,在时间d到来之前无法再进行领取操作。每次领取的策略是取当前可领取红包中w最大的,w相同时取d最大的。再给m个干扰机会,一个干扰机会可以使其在任意一个x这个时间点无法进行领取操作直到x+1。问最优使用不超过m次干扰下,将领取的最小红包价值总和。
题解:
dp[i][j]代表在i时间点前使用了j次disturb所能获得的最少的金额。
1.对于时间点T没有红包可以拿,这个金额就顺延到下一个时刻T+1
          dp[i+1][j] = dp[i][j]
2.如果有红包可以拿,有两种转移方式:
a.不disturb:那么就拿了红包,转移到d+1时间点。
          dp[min(tmp.d + 1, n + 1ll)][l] = min(dp[min(tmp.d + 1, n + 1ll)][l], dp[i][l] + tmp.w);
b.如果还有disturb的机会:就可以不拿红包,转移到T+1时间点。
         dp[i + 1][l] = min(dp[i + 1][l], dp[i][l - 1]);

  1. #include<iostream>
  2. #include<queue>
  3. #include<algorithm>
  4. using namespace std;
  5. typedef long long ll;
  6. const int maxt = 1e5 + 500;
  7. const int maxm = 250;
  8. int n, m, k;
  9. ll dp[maxt][maxm];
  10. void init() {
  11. for (int i = 2; i < maxt; i++)
  12. for (int j = 0; j < maxm; j++)
  13. dp[i][j] = 1e18;
  14. }
  15. struct Ev {
  16. ll s, t, d, w;
  17. bool operator<(const Ev& a)const {
  18. if (w == a.w)
  19. return d < a.d;
  20. return w < a.w;
  21. }
  22. }e[100005];
  23. bool cmp(Ev a, Ev b) {
  24. if (a.s == b.s) {
  25. if (a.w == b.w) {
  26. return a.d > b.d;
  27. }
  28. return a.w > b.w;
  29. }
  30. return a.s < b.s;
  31. }
  32. priority_queue<Ev> q;
  33. int main() {
  34. init();
  35. cin >> n >> m >> k;
  36. for (int i = 1; i <= k; i++) {
  37. cin >> e[i].s >> e[i].t >> e[i].d >> e[i].w;
  38. }
  39. sort(e + 1, e + 1 + k, cmp);
  40. int j = 1;
  41. for (int i = 1; i <= n; i++) {
  42. for (; j <= k;) {
  43. if (e[j].s <= i) {
  44. q.push(e[j]);
  45. j++;
  46. }
  47. else break;
  48. }
  49. while (!q.empty() && q.top().t < i)
  50. q.pop();
  51. if (q.empty()) {
  52. for (int l = 0; l <= m; l++) {
  53. dp[i + 1][l] = min(dp[i + 1][l], dp[i][l]);
  54. }
  55. continue;
  56. }
  57. Ev tmp = q.top();
  58. for (int l = 0; l <= m; l++) {
  59. dp[min(tmp.d + 1, n + 1ll)][l] = min(dp[min(tmp.d + 1, n + 1ll)][l], dp[i][l] + tmp.w);
  60. }
  61. for (int l = 1; l <= m; l++) {
  62. dp[i + 1][l] = min(dp[i + 1][l], dp[i][l - 1]);
  63. }
  64. }
  65. ll ans = 1e18;
  66. for (int i = 0; i <= m; i++) {
  67. ans = min(ans, dp[n + 1][i]);
  68. }
  69. cout << ans << endl;
  70. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注