topcode srm SRM 557 div2
这是今年长春赛之前最后一次写博客了,心理还是很紧张的,毕竟这还是我第一次参加regional ,看题目心不在焉,不思考的不仔细,代码出错率搞,code时容易犯各种脑残的错误……可能这就是什么赛前综合症吧,归根结底还是水平太菜呀
250pt if else 的基础编程题就不说了
500pt 点数才10,用二进制枚举所有可能取变成魔法少女的点,然后顺着题意看这种局面是否存在,然后取最优值即可
1000pt
很明显当n为奇数数,答案为0
n为偶数的时候, U 和 D 各占一半 ,然后用点技巧就是用ac自动机来构建状态(虽然有点大财小用),但是还是比较方便的编程复查度都很低,来表示当前这个串的结尾情况
很容易想到的一种状态就是
dp1[ i ] [ j ][ state ] U的个数为i, D 的个数为 j ,结尾的状态为state 并且已经匹配了 history 串了
dp2[ i ] [ j ][ state ] U的个数为i, D 的个数为 j ,结尾的状态为state 并且没有匹配了 history 串
仔细想想其实dp1没有必要搞成三维 ,表示成dp [ i ] [ j ] 就够了
贴上代码:
500pt
bool vis[15],g[15][15],ok; int bit[1024],n; class IncubatorEasy { public: void dfs(int u,int state) { //cout<<u<<" "<<state<<endl; if(!ok) return; for(int i=0;i<n;i++) if(g[u][i]&&!vis[i]) { vis[i]=1; if(state&(1<<i)) { ok=0;break; } dfs(i,state); } } int judge(int state) { ok=1; memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) if((1<<i)&state) { dfs(i,state); if(!ok) break; } return ok; } int maxMagicalGirls(vector <string> love) { for(int i=1;i<1024;i++) bit[i]=bit[i>>1]+(i&1); n=love.size(); for(int i=0;i<n;i++) for(int j=0;j<n;j++) g[i][j]=(love[i][j]=='Y'); int ret=0; for(int i=(1<<n)-1;i>0;i--) if(judge(i)) ret=max(ret,bit[i]); return ret; }
const int mod=1000000009; int chd[55][2],fail[55],sz,sw[127],word[55]; char ss[55]; int dp1[30][30][55],dp2[30][30][55]; void ins(char *s) { int p=0; for(;*s;s++) { int id=sw[*s]; if(!chd[p][id]) { memset(chd[sz],0,sizeof(chd[sz])); word[sz]=0; chd[p][id]=sz++; } p=chd[p][id]; } word[p]=1; } int Que[55]; void ac() { int *s=Que,*e=Que; if(chd[0][0]) fail[chd[0][0]]=0,*e++=chd[0][0]; if(chd[0][1]) fail[chd[0][1]]=0,*e++=chd[0][1]; while(s!=e) { int p=*s++; for(int i=0;i<2;i++) if(chd[p][i]) { *e++=chd[p][i]; fail[chd[p][i]]=chd[fail[p]][i]; word[chd[p][i]]|=word[fail[chd[p][i]]]; }else chd[p][i]=chd[fail[p]][i]; } } class FoxAndMountain { public: int count(int n, string h) { if(n&1) return 0; //cout<<n<<" "<<h<<endl; sw['U']=0; sw['D']=1; for(int i=0;i<h.length();i++) ss[i]=h[i]; ss[h.length()]='\0'; memset(chd[0],0,sizeof(chd[0])); sz=1; ins(ss); ac(); //cout<<sz<<endl; memset(dp1,0,sizeof(dp1)); memset(dp2,0,sizeof(dp2)); dp1[0][0][0]=1; for(int i=0;i<=n/2;i++) for(int j=0;j<=i;j++) for(int r=0;r<sz;r++) if(dp1[i][j][r]) { int next=chd[r][0]; if(word[next]) dp2[i+1][j][next]=(dp2[i+1][j][next]+dp1[i][j][r])%mod; else dp1[i+1][j][next]=(dp1[i+1][j][next]+dp1[i][j][r])%mod; if(i!=j){ next=chd[r][1]; if(word[next]) dp2[i][j+1][next]=(dp2[i][j+1][next]+dp1[i][j][r])%mod; else dp1[i][j+1][next]=(dp1[i][j+1][next]+dp1[i][j][r])%mod; } } for(int i=0;i<=n/2;i++) for(int j=0;j<=i;j++) for(int r=0;r<sz;r++) if(dp2[i][j][r]) { int next=chd[r][0]; dp2[i+1][j][next]=(dp2[i+1][j][next]+dp2[i][j][r])%mod; if(i!=j){ next=chd[r][1]; dp2[i][j+1][next]=(dp2[i][j+1][next]+dp2[i][j][r])%mod; } } //cout<<"bug"<<endl; int ret=0; for(int i=0;i<sz;i++) ret=(ret+dp2[n/2][n/2][i])%mod; return ret; }