(File IO): input:noip.in output:noip.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet
题目描述
你知道
N
e
w
O
r
a
n
g
e
I
n
d
u
s
t
r
y
P
a
l
a
t
a
b
l
e
New Orange Industry Palatable
NewOrangeIndustryPalatable公司吗?这是老板
S
m
a
r
t
Smart
Smart为了与苹果公司竞争而新开的一家橘子公司,它的业务是栽培美味的橘子并售卖,公司简称为
N
O
I
P
NOIP
NOIP。
N
O
I
P
NOIP
NOIP公司新推出
N
+
1
N+1
N+1个橘子,每个橘子上都贴有一个标签,其中有N个普通的橘子上面印有一个
"
N
"
"N"
"N"或
"
O
"
"O"
"O"或
"
I
"
"I"
"I"字母。还有一个独一无二的幸运橘子标签印有
"
P
"
"P"
"P"字母。
N
O
I
P
NOIP
NOIP公司搞了一个优惠活动,把N个普通橘子排成一排,从左到右依次编号为
1
~
N
1~N
1~N。让顾客从左到右选三个橘子,如果依次排列组成了
"
N
O
I
"
"NOI"
"NOI",就可获得优惠券。
S
m
a
r
t
Smart
Smart想把贴有标签P的幸运橘插入到排列中的(可以插入到队列的任意位置)。在换取优惠券时,
P
P
P橘子可以作为
N
N
N橘子或
O
O
O橘子或I橘子使用。
S
m
a
r
t
Smart
Smart想知道加入
P
P
P橘子以后,第一个选购的顾客最多有多少种选法可以得到优惠券。
输入
第一行是一个整数
N
N
N,表示
N
O
I
P
NOIP
NOIP公司有
N
N
N个普通橘子。
第二行是一个长度为
N
N
N的字符串S,仅由
N
,
O
,
I
N,O,I
N,O,I三个大写英文字母组成。字符串的左数第
i
i
i个字母表示第
i
i
i个橘子的标签类型。
输出
输出为一行,表示选择方式的最大值。
样例输入
样例输入1
5
NOIOI
样例输入2
7
NNNOIII
样例输出
样例输出1
6
样例输出2
18
数据范围限制
30
30
30%的数据:
3
≤
N
≤
20
3≤N≤20
3≤N≤20;
60
60
60%的数据:
3
≤
N
≤
200
3≤N≤200
3≤N≤200;
80
80
80%的数据:
3
≤
N
≤
3000
3≤N≤3000
3≤N≤3000;
100
100
100%的数据:
3
≤
N
≤
100000
3≤N≤100000
3≤N≤100000。
提示
样例
1
1
1中将
"
P
"
"P"
"P"放在
"
N
O
I
O
I
"
"NOIOI"
"NOIOI"中
"
N
"
"N"
"N"前一个位置或后一个位置,并将
"
P
"
"P"
"P"作为
N
N
N橘子使用,最多有6种选法可以得到优惠券。
样例
2
2
2中将"P"放在
"
N
N
N
O
I
I
I
"
" NNNOIII "
"NNNOIII"中
"
O
"
"O"
"O"前一个位置或后一个位置,并将
"
P
"
"P"
"P"作为
O
O
O橘子使用,最多有
18
18
18种选法可以得到优惠券。
解题思路
一系模拟+一系列优化,具体看看代码里的解释吧。。。
代码
#include<bits/stdc++.h>
using namespace std;
string s;
long long n,sn,si,an,ai,ao,ans,a[100005],b[100005];
int main(){
freopen("noip.in","r",stdin);
freopen("noip.out","w",stdout);
scanf("%d",&n);
cin>>s;
for(int i=0;i<n;i++)
if(s[i]=='I')
si++;//先统计I的个数
for(int i=0;i<n;i++)
{
if(s[i]=='N')sn++;//前面N的个数(包括本身)
a[i]=sn;
if(s[i]=='I')si--;//后面I的个数(包括本身)
b[i]=si;
if(s[i]=='O')
ans+=a[i]*b[i],an+=sn,ai+=si;//计算插入O会增加几个方案数~
}
for (int i=0;i<n;i++)ao=max(ao,a[i]*b[i]);//然后一系列比较
ans+=max(ao,max(an,ai));//接着还是一系列比较
printf("%lld",ans);
}