DP-Easy Problem - CodeForces - 1096D

DP-Easy Problem - CodeForces - 1096D

题意:

给 定 一 个 长 度 为 n 的 字 符 串 s , 可 以 删 除 任 意 位 置 上 的 字 母 , 删 除 第 i 位 的 字 母 需 要 花 费 代 价 a [ i ] 。 要 以 最 小 代 价 使 得 s 中 不 存 在 子 串 “ h a r d ” , 求 最 小 代 价 。 给定一个长度为n的字符串s,可以删除任意位置上的字母,删除第i位的字母需要花费代价a[i]。\\要以最小代价使得s中不存在子串“hard”,求最小代价。 nsia[i]使shard

Input:
6
hhardh
3 2 9 11 7 1

Output:
5


Input:
8
hhzarwde
3 2 6 9 4 8 7 1

Output:
4


Input:
6
hhaarr
1 2 3 4 5 6

Output:
0

数据范围:

n ∈ [ 1 , 100000 ] , a i ∈ [ 1 , 998244353 ] 。 T i m e   l i m i t : 2000 m s , M e m o r y   l i m i t : 262144 k B n∈[1,100000],a_i∈[1,998244353]。\\Time\ limit:2000 ms,Memory \ limit:262144 kB n[1,100000]ai[1,998244353]Time limit2000msMemory limit262144kB

题解:

字 符 串 中 是 否 存 在 “ h a r d ” 其 实 与 “ h a r ” 是 否 存 在 有 直 接 关 系 , 而 “ h a r ” 是 否 存 在 与 “ h a ” 是 否 存 在 有 关 . . .   设 d p [ i ] [ 1 ] : 使 得 前 i 个 字 符 当 中 不 存 在 “ h ” 所 需 花 费 的 最 小 代 价 。 d p [ i ] [ 2 ] : 使 得 前 i 个 字 符 当 中 不 存 在 “ h a ” 所 需 花 费 的 最 小 代 价 。 d p [ i ] [ 3 ] : 使 得 前 i 个 字 符 当 中 不 存 在 “ h a r ” 所 需 花 费 的 最 小 代 价 。 d p [ i ] [ 4 ] : 使 得 前 i 个 字 符 当 中 不 存 在 “ h a r d ” 所 需 花 费 的 最 小 代 价 。   则 每 种 情 况 与 前 者 的 关 系 : d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j ] + a [ i ] ) , 就 是 当 前 字 母 删 除 与 否 的 关 系 。   若 不 删 除 第 i 个 字 母 , 那 么 前 i − 1 个 字 母 当 中 不 存 在 第 i 个 字 母 的 前 缀 。 若 删 除 第 i 个 字 母 , 则 当 前 代 价 为 相 同 情 况 下 前 i − 1 个 字 母 的 代 价 , 再 加 上 a [ i ] 。 字符串中是否存在“hard”其实与“har”是否存在有直接关系,而“har”是否存在与“ha”是否存在有关...\\\ \\设dp[i][1]:使得前i个字符当中不存在“h”所需花费的最小代价。\\\quad dp[i][2]:使得前i个字符当中不存在“ha”所需花费的最小代价。\\\quad dp[i][3]:使得前i个字符当中不存在“har”所需花费的最小代价。\\\quad dp[i][4]:使得前i个字符当中不存在“hard”所需花费的最小代价。\\\ \\则每种情况与前者的关系:dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+a[i]),就是当前字母删除与否的关系。\\\ \\若不删除第i个字母,那么前i-1个字母当中不存在第i个字母的前缀。\\若删除第i个字母,则当前代价为相同情况下前i-1个字母的代价,再加上a[i]。 hardharharha... dp[i][1]:使ihdp[i][2]:使ihadp[i][3]:使ihardp[i][4]:使ihard :dp[i][j]=min(dp[i1][j1],dp[i1][j]+a[i]) ii1iii1a[i]

注意:
① 、 边 界 的 处 , j = 0 的 情 况 赋 值 为 i n f 。 ② 、 更 新 要 及 时 。 ③ 、 根 据 a i 的 范 围 , i n f 需 要 大 于 1 0 10 ①、边界的处,j=0的情况赋值为inf。\\②、更新要及时。\\③、根据a_i的范围,inf需要大于10^{10} j=0infaiinf1010


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define ll long long
using namespace std;
const ll inf=1e17;
const int N=1e5+10;
char s[N];
int a[N],n;
ll dp[N][5];  ///1:不出现h  2:不出现ha  3:不出现har  4:不出现hard
char hard[]="#hard";

int main ()
{
    cin>>n;
    scanf("%s",s+1);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);

    for (int i=1;i<=n;i++) dp[i][0]=inf;
    if(s[1]=='h') dp[1][1]=a[1];

    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=4;j++)
        {
            if(s[i]!=hard[j])
            {
                dp[i][j]=dp[i-1][j];
                continue;
            }
            dp[i][j]=min(dp[i-1][j-1],dp[i-1][j]+a[i]);
        }
    }

    printf("%lld\n",dp[n][4]);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值