topcode srm SRM 557

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比赛吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值