zoukankan      html  css  js  c++  java
  • Codeforces 1107F(dp)

    怎么就没人解释一下为啥用b排序可以保证正确性呢……太菜了,理解了好久。

    时间流逝价值会丢失的背包,类似题洛谷1417

    本题与洛谷1417不同之处在于流逝是有截止的。

    1.这个dp[j]的含义是:最后跑路时欠了j个费所得到的最大钱数。

    2.假设是不排序的,直接去背包,考虑两种转移,一种是选了当前这个以后到最后时欠的个数并不增多(即这个的k天都还了);另一种是这个也没还完。

    3.如果直接都还了那顺序完全无所谓了,但是如果有这么几个都是最后要欠的,那么显然第一个要支付0天(即提钱当天就跑路了),第二个要支付1天,……第j个支付(j - 1)天。那么无论列一列式子(如洛谷1417)还是直观感受,反正就是这么几个,那肯定贪心地、尽量少扣大的b。这就是要按b从大到小排序的原因。

    4.取dp[0~n]的最大值。

     1 const int maxn = 550;
     2 int n;
     3 struct off {
     4     ll a, b, k;
     5 
     6     bool operator < (const off &rhs) const {
     7         return b > rhs.b;
     8     }
     9 }offer[maxn];
    10 ll dp[maxn];
    11 
    12 int main() {
    13     cin >> n;
    14     rep(i, 1, n)    cin >> offer[i].a >> offer[i].b >> offer[i].k;
    15 
    16     sort(offer + 1, offer + 1 + n);
    17     rep(i, 1, n) {
    18         irep(j, i, 0) {
    19             dp[j] = max(dp[j], dp[j] + offer[i].a - offer[i].b * offer[i].k);
    20             if (j)  dp[j] = max(dp[j], dp[j - 1] + offer[i].a - offer[i].b * (j - 1));
    21         }
    22     }
    23 
    24     cout << *max_element(dp, dp + n + 1) << endl;
    25     return 0;
    26 }
  • 相关阅读:
    Qt 学习
    Qt 串口连接
    GitKraken使用教程-基础部分(9)
    GitKraken使用教程-基础部分(8)
    GitKraken使用教程-基础部分(7)
    GitKraken使用教程-基础部分(6)
    GitKraken使用教程-基础部分(5)
    GitKraken使用教程-基础部分(4)
    GitKraken使用教程-基础部分(3)
    C++ 利用template给函数中的变量赋初值
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10657836.html
Copyright © 2011-2022 走看看