【洛谷 P1371】NOI元丹(枚举+乱搞)
【题解】【乱搞】
【水题来袭!】
【先预处理出不添加元素时可以组成的"NOI"的个数。N[i]表示正序计算到第i位'N'的个数,I[i]表示倒序计算到第i位'I'的个数。然后从前往后枚举‘O’,每次将N[i]*I[i]加入答案】
【然后,从前往后枚举在每个位置放'O'所多出来的方案数,或是当当前位置是‘O’时,在它前面多加一个'N'或在它后面多加一个'I'所多出来的方案数,在这三种情况中取最优值】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
char s[100010];
int n,N[100010],I[100010],tot;
ll ans,maxn;
int main()
{
int i,j;
scanf("%d\n",&n);
gets(s+1);
for(i=1;i<=n;++i)
if(s[i]=='N') N[i]=N[i-1]+1;
else N[i]=N[i-1];
for(i=n;i>0;--i)
if(s[i]=='I') I[i]=I[i+1]+1;
else I[i]=I[i+1];
for(i=2;i<n;++i)
if(s[i]=='O') ans+=(N[i]*I[i]);
for(i=1;i<=n;++i)
{
ll s3=N[i]*I[i+1];
maxn=max(s3,maxn);
}
ll s1=0,s2=0;
for(i=1;i<=n;++i)
if(s[i]=='O') s1+=I[i];
for(i=n;i>0;--i)
if(s[i]=='O') s2+=N[i];
s1=max(s1,s2); maxn=max(maxn,s1);
printf("%lld\n",maxn+ans);
return 0;
}
既然无能更改,又何必枉自寻烦忧