洛谷 P1371 NOI元丹

来源:互联网 发布:网络文学社是干什么的 编辑:程序博客网 时间:2024/04/28 01:56

题目描述
小A打算开始炼NOI元丹(什么鬼),据说吃了可以提高NOI时的成绩。
是这么练的。元丹有三种元核,’N’,’O’,’I’。现有很多个这样原核,按顺序排成一行。炼元丹时,从左往右分别挑出’N’,’O’,’I’三个原核吞下。
现在他关心,有几种服用方式……且慢!
他觉得服用方式太少,以至于不能成仙。所以他可以通过某个途径,得到’N’,’O’,’I’的三种原核中的任意一个,至于哪一种由他决定。然后他将获得这个原核的插入到这一排原核中的任意位置(包括最前最后)。
现在你要知道,新的元核序列中能有多少种’N’,’O’,’I’的取出方式。子串的字母并不要求连续。


【题目分析】
枚举。


【代码】

#include <cstdio>#include <cmath>#include <cstring>#include <iostream>#include <algorithm>#define ll long longusing namespace std;int f[100010],g[100010],o[100010]; //从前往后的n的前缀和, g的后缀和,是不是o char s[100010];int l;int main(){    scanf("%d",&l);    scanf("%s",s+1);    for (int i=1;i<=l;++i)    {        f[i]=f[i-1];        if (s[i]=='O') o[i]=1;        if (s[i]=='N') f[i]++;        if (s[i]=='I') g[i]++;    }    for (int i=l;i>=1;--i) g[i]+=g[i+1];    long long ans=0;    long long tmp=0;    for (int i=1;i<=l;++i)        if (o[i]) tmp+=((ll)f[i]+1)*(ll)g[i];//    printf("put a N before ans is %lld\n",tmp);    ans=max(ans,tmp);    tmp=0;    for (int i=1;i<=l;++i)        if (o[i]) tmp+=(ll)f[i]*((ll)g[i]+1);//    printf("put a I behind ans is %lld\n",tmp);     ans=max(ans,tmp);    tmp=0;    for (int i=1;i<=l;++i)        if (o[i]) tmp+=(ll)g[i]*(ll)f[i];//    printf("nothing is %lld\n",tmp);    long long maxx=0;    for (int i=1;i<=l;++i) maxx=max(maxx,(ll)f[i]*(ll)g[i]);    tmp+=maxx;    ans=max(ans,tmp);//    printf("put a O in is %lld\n",tmp);    printf("%lld\n",ans);}
0 0
原创粉丝点击