考场上写挂了一个小地方,然后WA了。。。还好躺一手hls,复制D的代码改变量名交了,还上了点分,我还是菜啊
据说正着贪一遍反着贪一遍有一个行就ans++,然后这样就可以A了,甚至还有直接贪A掉的。还不知道什么操作
top[j]表示从i开始到j还有多少个没有被 ) 匹配掉的 (
cnt[j]表示从i开始到j还有多少个没有 ) 和 ? 匹配掉的 (
top2[j]表示从i开始到j还有多少个不需要和 ( 匹配的 ?
这样就可以DP了,难道这就是贪心?
#include<cstdio>
#include<cstring>
#define maxl 5010
int top[maxl],n,top2[maxl],ans;
int sta[maxl],cnt[maxl];
char s[maxl];
bool vis[maxl][maxl];
int main()
{
memset(vis,true,sizeof(vis));
scanf("%s",s+1);;
n=strlen(s+1);
bool flag=false;
for(int i=1;i<=n;i++)
{
memset(top,0,sizeof(top));
memset(top2,0,sizeof(top2));
memset(cnt,0,sizeof(cnt));
memset(sta,0,sizeof(sta));
for(int j=i;j<=n;j++)
{
if(s[j]=='(')
{
top[j]=top[j-1]+1;sta[top[j]]=j;
cnt[j]=cnt[j-1]+1;top2[j]=top2[j-1];
vis[i][j]=false;
continue;
}
if(s[j]==')')
{
if(top[j-1]>0)
{
if(cnt[j-1]<cnt[sta[top[j-1]]])
{
cnt[j]=cnt[j-1];
top2[j]=top2[j-1]+1;
if(cnt[j]>0 && top2[j]>0)
top2[j]--,cnt[j]--;
top[j]=top[j-1]-1;
}
else
{
cnt[j]=cnt[j-1]-1;
top2[j]=top2[j-1];
top[j]=top[j-1]-1;
}
if((top[j]==0 && top2[j]%2==0) ||
(cnt[j]==0 && top2[j]%2==0))
ans++;
}
else
{
if(top2[j-1]>0)
{
cnt[j]=cnt[j-1];//0
top2[j]=top2[j-1]-1;
top[j]=top[j-1];//0
}
else
break;
if(top2[j]%2==0)
ans++;
}
}
if(s[j]=='?')
{
if(cnt[j-1]>0)
{
cnt[j]=cnt[j-1]-1;
top2[j]=top2[j-1];//0
top[j]=top[j-1];
}
else
{
cnt[j]=cnt[j-1]; //0
top2[j]=top2[j-1]+1;
top[j]=top[j-1];
}
if((top[j]==0 && top2[j]%2==0) ||
(cnt[j]==0 && top2[j]%2==0))
ans++;
}
}
}
printf("%d",ans);
return 0;
}