ABC 261.D - Flipping and Bonus (dp)

https://atcoder.jp/contests/abc261/tasks/abc261_d
https://blog.csdn.net/qq_51376774/article/details/125955954?spm=1001.2014.3001.5501

问题陈述
抛硬币N次,有一个计数器,最初显示为0。

根据第i次抛硬币的结果,会发生以下情况:

如果它是正面的:将计数器的值增加1并得到Xi;
如果它是反面的:将计数器的值设为0(不加Xi)。
此外,有M种连胜奖金。

求能收到的最大金额。
Sample Input 1 Copy
6 3
2 7 1 8 2 8
2 10
3 1
5 5
Sample Output 1 Copy
48
If he gets head, head, tail, head, head, head, in this order, the following amounts of money are awarded.(头头尾头头头)

In the 1-st coin toss, the coin heads. Change the counter's value from 0 to 1 and receive 2 yen.
In the 2-nd coin toss, the coin heads. Change the counter's value from 1 to 2 and receive 7 yen. Additionally, get 10 yen as a streak bonus.
In the 3-rd coin toss, the coin tails. Change the counter's value from 2 to 0.
In the 4-th coin toss, the coin heads. Change the counter's value from 0 to 1 and receive 8 yen.
In the 5-th coin toss, the coin heads. Change the counter's value from 1 to 2 and receive 2 yen. Additionally, get 10 yen as a streak bonus.
In the 6-th coin toss, the coin heads. Change the counter's value from 22 to 3 and receive 8 yen. Additionally, get 1 yen as a streak bonus.
max操作:2+(7+10)+0+8+(2+10)+(8+1)=48
//#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<string>
#include<cstdio>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<deque>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=200200;
const int M=5002;
const int mod=998244353;
LL a[N],f[M][M];
LL mp[N];
int b[N];
bool vis[N];
int dx[]={-1,0,0,1},dy[]={0,1,-1,0};
string s[N];
int main()
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
    int T=1;
    //cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            cin>>a[i];
        for(int i=1;i<=m;i++)
        {
            LL x,y;
            cin>>x>>y;
            mp[x]=y;
        }
        //f[i][j]共抛出i次且计数器为j
        for(int i=1;i<=n;i++)//共抛了i次硬币
        {
            for(int j=1;j<=i;j++)//计数器为j
            {
                //让当前所抛出的硬币通通体验一下处于什么位置时候的值
                f[i][j]=f[i-1][j-1]+a[i]+mp[j];
            }
            f[i][0]=0;
            for(int k=1;k<i;k++)
            {
                //记录上一行操作下能够得到的最大的值
                //放在第0个的位置是为了满足上边当计数器为1的时候
                f[i][0]=max(f[i][0],f[i-1][k]);
            }
        }
        /*for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=n;j++)
            {
                cout<<f[i][j]<<" ";
            }
            cout<<endl;
        }*/
        LL maxn=0;
        for(int i=1;i<=n;i++)
            maxn=max(maxn,f[n][i]);
        cout<<maxn<<endl;
    }
    return 0;
}
posted @ 2022-07-29 17:21  Vijurria  阅读(70)  评论(0编辑  收藏  举报