Codeforces 1096 D. Easy Problem(dp)

题目链接
题目大意:
给定一个字符串,每个字符有自己的权值,可以对字符串进行操作,每次操作可以删除一个字符,花费就是这个字符的权值,问在保证没有子序列“hard”存在的最小花费是多少?

解题思路:
动态规划,dp[i][sta]表示前i个字符串没有出现sta这个子序列的最小花费,sta共有四个值,0:“h”,1:“ha”,2:“har”,3:“hard”。
对于不是“hard”这四个字符的则对当前状态没有影响。
对于字符:
“h”:影响sta=0,这个是一定要删掉的。
“a”:影响sta=1,如果保留这个‘a’得保证前面没有“h”存在,如果删掉这个‘a’的得保证前面也没有“ha”存在的情况,这样才能保证到当前没有“ha”存在。
“r”:影响sta=2, 如果保留这个‘r’得保证前面没有“ha”存在,删掉这个‘r’则得保证前面也没有“har”存在,这样才能保证到当前没有“har”存在。
“d”:影响sta=3, 如果保留这个‘d’得保证没有前面没有“har”存在,删掉这个‘d’则得保证前面也没有“hard”存在,这样才能保证到当前没有“hard”存在。
最后的答案就是dp[n][3]。

解题代码:

#include<bits/stdc++.h>
using namespace std;
mt19937 rng_32(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
const int maxn=1e5+10;
ll dp[maxn][4];
char s[maxn];
ll a[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",s+1);
    for (int i=1;i<=n;i++)
    scanf("%I64d",&a[i]);
    for (int i=1;i<=n;i++)
    {
        for (int j=0;j<4;j++)
        dp[i][j]=dp[i-1][j];
        if (s[i]=='h')
            dp[i][0]=dp[i-1][0]+a[i];
        else if (s[i]=='a')
            dp[i][1]=min(dp[i-1][0],dp[i-1][1]+a[i]);
        else if (s[i]=='r')
            dp[i][2]=min(dp[i-1][1],dp[i-1][2]+a[i]);
        else if (s[i]=='d')
            dp[i][3]=min(dp[i-1][2],dp[i-1][3]+a[i]);
    }
    cout<<dp[n][3];
    return 0;
}
发布了12 篇原创文章 · 获赞 1 · 访问量 327

猜你喜欢

转载自blog.csdn.net/qq_41818939/article/details/104750454