当前位置:   article > 正文

Codeforces Round 932 (Div. 2)C. Messenger in MAC 有序简化题目,dp,dp优化

Codeforces Round 932 (Div. 2)C. Messenger in MAC 有序简化题目,dp,dp优化

Problem - C - Codeforces

目录

题意:

思路:

状态转移方程:

参考代码:


题意:

给两个长度为n数组a,b,和整数 l

任取若干下标,使得这个式子

不超过 l 的最多下标数。

思路:

可以根据右侧部分排好序依次减。

所以我们先对数组排序,按b的大小排。

然后用动态规划下标 i 之前 取 j 个 的最小值。

dp [ i ] [ j ]  =  dp [ k ] [ j -1 ]  + a[ i ] + b[ i ] - b[ k ]

k是指 i 之前的,取 j - 1个时的最小dp的下标。

但是这里有个k就三维了,不过我们可以这样优化:

 dp [ i ] [ j ]  =  dp [ k ] [ j -1 ] - b[ k ] + a[ i ] + b[ i ]

用 g[ j-1 ] = dp[ k ][j - 1] - b[ k ]

即 g[ j ] = dp[ k ][ j ] - b[ k ]

代表此前取 j 次最小的dp[ k ][ j ] - b[ k ]

我们在dp的过程中一直维护这个g[ j ]即可。

所以

状态转移方程

dp [ i ] [ j ]  = g[ j ] + a[ i ] + b[ i ]

然后就可以去找数目最多的小于 l 的结果了。

参考代码:

注意dp时不能先次数再下标,因为本次可能为了更小,取了更靠后的数。。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. #define endl "\n"
  5. #define int long long
  6. const ll inf = 1e9;
  7. const ll MOD = 0x77777777737;
  8. const int maxn = 1e9;
  9. int dp[2003][2003];
  10. void solve()
  11. {
  12. int n, l;
  13. cin >> n >> l;
  14. vector<int>a(n), b(n),c(n),g(n+1);
  15. for (int i = 0; i < n; i++)
  16. {
  17. cin >> a[i] >> b[i];
  18. }
  19. iota(c.begin(), c.end(),0);
  20. sort(c.begin(), c.end(), [&](int l,int r)
  21. {
  22. return b[l] < b[r];
  23. });
  24. for (int i = 1; i <= n; i++)
  25. g[i] = LLONG_MAX;
  26. for (int i = 0; i < n; i++)
  27. {
  28. for (int j = i+1; j > 1; j--)//个数
  29. {
  30. //dp[i][j] = dp[k][j-1]-b[k]+a[c[i]]+b[c[i]];
  31. dp[i][j] = g[j-1]+a[c[i]]+b[c[i]];
  32. g[j] = min(dp[i][j] - b[c[i]],g[j]);
  33. }
  34. dp[i][1] = a[c[i]];
  35. g[1] = min(g[1],a[c[i]] -b[c[i]]);
  36. }
  37. //再用g去统计一下答案
  38. for (int i = 1; i <= n; i++)
  39. g[i] = LLONG_MAX;
  40. for (int i = 0; i < n; i++)
  41. {
  42. for (int j = i + 1; j >= 1; j--)//个数
  43. {
  44. g[j] = min(g[j], dp[i][j]);
  45. }
  46. }
  47. for (int i = n; i >= 0; i--)
  48. {
  49. if (g[i] <= l)
  50. {
  51. cout << i << endl;
  52. return;
  53. }
  54. }
  55. }
  56. signed main()
  57. {
  58. ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
  59. int t = 1;
  60. cin >> t;
  61. while (t--)
  62. {
  63. solve();
  64. }
  65. return 0;
  66. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/236707?site
推荐阅读
相关标签
  

闽ICP备14008679号