打卡信奥刷题(997)用C++实现信奥 P1371 NOI元丹

P1371 NOI元丹

题目描述

小A打算开始炼 NOI\texttt{NOI}NOI 元丹(什么鬼),据说吃了可以提高 NOI\texttt{NOI}NOI 时的成绩。

是这么练的。元丹有三种元核,NOI。现有很多个这样原核,按顺序排成一行。炼元丹时,从左往右分别挑出 NOI 三个原核吞下。

现在他关心,有几种服用方式……且慢!

他觉得服用方式太少,以至于不能成仙。所以他可以通过某个途径,得到 NOI 的三种原核中的任意一个,至于哪一种由他决定。然后他将获得这个原核的插入到这一排原核中的任意位置(包括最前最后)。

现在你要知道,新的元核序列中能有多少种 NOI 的取出方式。子串的字母并不要求连续。

输入格式

第一行,一个整数 NNN,表示字符串的长度。

第二行,一行字符串,里面只有只有 NOI 三种字母。

输出格式

表示出最多可以提炼出来的 NOI\texttt{NOI}NOI 元丹的方案种数。

输入输出样例 #1

输入 #1

5
NOIOI

输出 #1

6

说明/提示

样例解释:

他可以获取一个 N 元核,加到最前面。

NNOIOI | NNOIOI | NNOIOI | NNOIOI | NNOIOI | NNOIOI
~ ~~   | ~ ~  ~ | ~   ~~ |  ~~~   |  ~~  ~ |  ~  ~~

对于 30%30\%30% 的数据 N≤200N \le 200N200

对于 50%50\%50% 的数据 N≤2000N \le 2000N2000

对于 100%100\%100% 的数据 3≤N≤1053 \le N \le 10 ^ 53N105

C++实现

#include
#include
#include
#include
#define maxn 100000+10
using namespace std;
string s;
long long N[maxn],O[maxn],I[maxn];//pre
long long n,sum[maxn],MAXN,MAXO,MAXI,MAXS;
int main()
{
cin>>n;
char temp=getchar();
s.push_back(‘0’);
for(int i=1;i<=n;i++)
{
temp=getchar();
if(temp==‘N’)
N[i]++;
if(temp==‘O’)
O[i]++;
if(temp==‘I’)
I[i]++;
N[i]+=N[i-1];
O[i]+=O[i-1];
I[i]+=I[i-1];
s.push_back(temp);
}
for(int i=1;i<=n;i++)
{
if(s[i]==‘O’)
{
sum[i]+=N[i-1](I[n]-I[i]);
MAXO=max(MAXO,N[i-1]
(I[n]-I[i]));
MAXN+=I[n]-I[i];
MAXI+=N[i-1];
}
sum[i]+=sum[i-1];
}
MAXS=max(MAXO,max(MAXN,MAXI));
cout<<sum[n]+MAXS;
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值