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;
}
1000pt
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;
}
我搞acm的时间其实不长了,希望我能放下紧张,好好享受剩下的每场acm比赛吧