@himnouth
2022-08-08T00:49:21.000000Z
字数 1194
阅读 280
题解
题目链接:https://atcoder.jp/contests/abc261/tasks/abc261_d
高桥将掷硬币次。 他还有一个计数器,最初显示为。
根据第次抛硬币的结果,他将执行以下操作:
此外,还有中类型的奖励。当计数器的值为时可获得第种连胜奖金奖励.
试求出高桥能收到的最大金额。
6 32 7 1 8 2 82 103 15 5
48
3 21000000000 1000000000 10000000001 10000000003 1000000000
5000000000
本题使用动态规划算法求解,解法如下:
令 表示将硬币抛次且计数器值为时的最大金额,则有:
若,则:
令为至中任意数,则有:
若,则:
令为至中任意数,若,则有:
对于第三种情况,可在枚举所有后单独枚举所有并将所有加上即可。
以上算法代码实现如下:
#include<bits/stdc++.h>using namespace std;#define N 5005int n,m;long long f[N][N],x[N],c[N],y[N]; //f[i][j]:共抛出i次且计数器为jint main(){memset(f,-0x3f,sizeof f);cin>>n>>m;for(int i=1;i<=n;i++){scanf("%d",&x[i]);}for(int i=1;i<=m;i++){scanf("%d %d",&c[i],&y[i]);}f[0][0]=0;for(int i=1;i<=n;i++){for(int k=1;k<i;k++) f[i][0]=max(f[i][0],f[i-1][k]);for(int j=1;j<=i;j++){f[i][j]=max(f[i][j],f[i-1][j-1]+x[i]);}for(int k=1;k<=m;k++){f[i][c[k]]+=y[k];}}long long ans=0;for(int i=0;i<=n;i++){ans=max(f[n][i],ans);}cout<<ans;return 0;}