[关闭]
@himnouth 2022-08-08T00:49:21.000000Z 字数 1194 阅读 280

题解

Atcoder Beginner Contest 261 Problem D 题解

题目链接:https://atcoder.jp/contests/abc261/tasks/abc261_d

题目大意

高桥将掷硬币次。 他还有一个计数器,最初显示为
根据第次抛硬币的结果,他将执行以下操作:

此外,还有中类型的奖励。当计数器的值为时可获得第种连胜奖金奖励.
试求出高桥能收到的最大金额。

样例输入1

  1. 6 3
  2. 2 7 1 8 2 8
  3. 2 10
  4. 3 1
  5. 5 5

样例输出1

  1. 48

样例输入2

  1. 3 2
  2. 1000000000 1000000000 1000000000
  3. 1 1000000000
  4. 3 1000000000

样例输出2

  1. 5000000000

数据范围

解析

本题使用动态规划算法求解,解法如下:
表示将硬币抛次且计数器值为时的最大金额,则有:

对于第三种情况,可在枚举所有后单独枚举所有并将所有加上即可。

代码实现

以上算法代码实现如下:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define N 5005
  4. int n,m;
  5. long long f[N][N],x[N],c[N],y[N]; //f[i][j]:共抛出i次且计数器为j
  6. int main(){
  7. memset(f,-0x3f,sizeof f);
  8. cin>>n>>m;
  9. for(int i=1;i<=n;i++){
  10. scanf("%d",&x[i]);
  11. }
  12. for(int i=1;i<=m;i++){
  13. scanf("%d %d",&c[i],&y[i]);
  14. }
  15. f[0][0]=0;
  16. for(int i=1;i<=n;i++){
  17. for(int k=1;k<i;k++) f[i][0]=max(f[i][0],f[i-1][k]);
  18. for(int j=1;j<=i;j++){
  19. f[i][j]=max(f[i][j],f[i-1][j-1]+x[i]);
  20. }
  21. for(int k=1;k<=m;k++){
  22. f[i][c[k]]+=y[k];
  23. }
  24. }
  25. long long ans=0;
  26. for(int i=0;i<=n;i++){
  27. ans=max(f[n][i],ans);
  28. }
  29. cout<<ans;
  30. return 0;
  31. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注