DP-牛客寒假集训营1- nico和niconiconi

48 篇文章 1 订阅

DP-牛客寒假集训营1- nico和niconiconi

题目:
在这里插入图片描述
题意:

给 定 一 个 字 符 串 给定一个字符串
对 于 子 串 “ n i c o ” 可 得 a 分 对于子串“nico”可得a分 nicoa
对 于 子 串 “ n i c o n i ” 可 得 b 分 对于子串“niconi”可得b分 niconib
对 于 子 串 “ n i c o n i c o n i ” 可 得 c 分 对于子串“niconiconi”可得c分 niconiconic
现 输 入 字 符 串 长 度 n , 分 数 a , b , c , 字 符 串 s 现输入字符串长度n,分数a,b,c,字符串s nabcs
问 s 的 最 大 得 分 是 多 少 问s的最大得分是多少 s

题解:

计 d p [ i ] 代 表 前 i 个 字 符 的 计 数 最 大 值 。 那 么 可 得 转 移 方 程 : 计 dp[i]代表前 i个字符的计数最大值。那么可得转移方程: dp[i]i

①、 i f ( s u b s t r i n g ( i − 3 , i ) = = n i c o ) , t h e n : d p [ i ] = m a x ( d p [ i ] , d p [ i − 4 ] + a ) if(substring(i-3,i)==nico) ,then: dp[i]=max(dp[i],dp[i-4]+a) if(substring(i3,i)==nico)thendp[i]=max(dp[i],dp[i4]+a)
②、 i f ( s u b s t r i n g ( i − 5 , i ) = = n i c o n i ) , t h e n : d p [ i ] = m a x ( d p [ i ] , d p [ i − 6 ] + b ) if(substring(i-5,i)==niconi),then: dp[i]=max(dp[i],dp[i-6]+b) if(substring(i5,i)==niconi)thendp[i]=max(dp[i],dp[i6]+b)
③、 i f ( s u b s t r i n g ( i − 9 , i ) = = n i c o n i c o n i ) , t h e n : d p [ i ] = m a x ( d p [ i ] , d p [ i − 10 ] + c ) if(substring(i-9,i)==niconiconi),then:dp[i]=max(dp[i],dp[i-10]+c) if(substring(i9,i)==niconiconi)thendp[i]=max(dp[i],dp[i10]+c)

最 后 输 出 d p [ n ] 即 可 。 最后输出 dp[n] 即可。 dp[n]

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e5+10;
int n;
ll a,b,c,dp[N];//dp[i]表示前i个字符的最大得分
string s;
int main()
{
    cin>>n>>a>>b>>c;
    cin>>s;
    for(int i=0;i<s.size();i++)
    {
        if(i>=1) dp[i]=dp[i-1];//首先每增加一个字符,得分应当大于等于前一项,因此先赋值为前一项的值,防止递推“断开”
        if(i>=3&&s.substr(i-3,4)=="nico")
            dp[i]=max(dp[i],dp[i-3]+a);//不选择子串"nico"和选择子串"nico"在此前基础得a分两者之间取最大
        if(i>=5&&s.substr(i-5,6)=="niconi")
            dp[i]=max(dp[i],dp[i-5]+b);
        if(i>=9&&s.substr(i-9,10)=="niconiconi")
            dp[i]=max(dp[i],dp[i-9]+c);
    }
    cout<<dp[n-1]<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值