BZOJ 2331 [SCOI2011]地板 ——插头DP

【题目分析】

    经典题目,插头DP。

    switch 套 switch 代码瞬间清爽了。

【代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define maxn 400005
const int md=20110520;
int dp[2][maxn],a[101][101],n,m,fac[15],tot,b[15];
char s[105];
void print(int x){F(i,0,m) printf("%d",(x%fac[i+1])/fac[i]);}
int main()
{
    scanf("%d%d",&n,&m);
    F(i,0,n-1){scanf("%s",s);F(j,0,m-1)a[i][j]=s[j]=='*'?1:0;}
    if (m>n){F(i,0,m-1)F(j,i+1,m-1)swap(a[i][j],a[j][i]);swap(m,n);}
//  F(i,0,n-1){F(j,0,m-1)printf("%d ",a[i][j]);printf("\n");}
    fac[0]=1;F(i,1,13)fac[i]=fac[i-1]*3;tot=fac[m+1]-1;
    int now=1,pre=0;
    memset(dp[now],0,sizeof dp[now]);
    dp[now][0]=1;
    F(i,0,n-1) F(j,0,m-1)
    {
         
        if (a[i][j])
        {
            now^=1;pre^=1;
            memset(dp[now],0,sizeof dp[now]);
            F(s,0,tot) if (dp[pre][s])
            {
//              printf("now is "); print(s); printf(" \n");
                int tmp1=(s%fac[j+1])/fac[j],tmp2=(s%fac[j+2])/fac[j+1],tmp=s;
                if (!tmp1&&!tmp2)
                {
                    (dp[now][s]+=dp[pre][s])%=md;
//                  printf(" to "); print(s); printf("\n");
                }
            }
        }
        else
        {
            now^=1;pre^=1;
            memset(dp[now],0,sizeof dp[now]);
            F(s,0,tot) if (dp[pre][s])
            {
//              printf("now is "); print(s); printf(" \n");
                int tmp1=(s%fac[j+1])/fac[j],tmp2=(s%fac[j+2])/fac[j+1],tmp=s;
                switch(tmp1)
                {
                    case 0:
                        switch(tmp2)
                        {
                            case 0:
                                tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
//                              printf(" to "); print(tmp+2*fac[j]+2*fac[j+1]); printf("\n");
                                (dp[now][tmp+2*fac[j]+2*fac[j+1]]+=dp[pre][s])%=md;
//                              printf(" to "); print(tmp+fac[j]); printf("\n");
                                (dp[now][tmp+fac[j]]+=dp[pre][s])%=md;
//                              printf(" to "); print(tmp+fac[j+1]); printf("\n");
                                (dp[now][tmp+fac[j+1]]+=dp[pre][s])%=md;
                            break;
                            case 1:
                                tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
//                              printf(" to "); print(tmp+fac[j]); printf("\n");
                                (dp[now][tmp+fac[j]]+=dp[pre][s])%=md;
//                              printf(" to "); print(tmp+2*fac[j+1]); printf("\n");
                                (dp[now][tmp+2*fac[j+1]]+=dp[pre][s])%=md;
                            break;
                            case 2:
                                tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
//                              printf(" to "); print(tmp); printf("\n");
                                (dp[now][tmp]+=dp[pre][s])%=md;
//                              printf(" to "); print(tmp+2*fac[j]); printf("\n");
                                (dp[now][tmp+2*fac[j]]+=dp[pre][s])%=md;
                            break;
                        }
                    break;
                    case 1:
                        switch(tmp2)
                        {
                            case 0:
                                tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
//                              printf(" to "); print(tmp+2*fac[j]); printf("\n");
                                (dp[now][tmp+2*fac[j]]+=dp[pre][s])%=md;
//                              printf(" to "); print(tmp+fac[j+1]); printf("\n");
                                (dp[now][tmp+fac[j+1]]+=dp[pre][s])%=md;
                            break;
                            case 1:
                                tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
//                              printf(" to "); print(tmp); printf("\n");
                                (dp[now][tmp]+=dp[pre][s])%=md;
                            break;
                            case 2:
                            break;
                        }
                    break;
                    case 2:
                        switch(tmp2)
                        {
                            case 0:
                                tmp-=tmp1*fac[j]; tmp-=tmp2*fac[j+1];
//                              printf(" to "); print(tmp+2*fac[j]); printf("\n");
                                (dp[now][tmp+2*fac[j+1]]+=dp[pre][s])%=md;
//                              printf(" to "); print(tmp); printf("\n");
                                (dp[now][tmp]+=dp[pre][s])%=md;
                            break;
                            case 1:
                            break;
                            case 2:
                            break;
                        }
                    break;
                }
            }
        }
        if (j==m-1)
        {
//          printf("On The last of road\n");
            now^=1;pre^=1;
            memset(dp[now],0,sizeof dp[now]);
            F(s,0,tot) if (dp[pre][s])
            {
//              printf("End with "); print(s);
                int tmp=s,tmp1=(s%fac[m+1])/fac[m];
                if (tmp1) {continue;}
                tmp*=3;
//              printf(" can become "); print(tmp); printf("\n");
                (dp[now][tmp]+=dp[pre][s])%=md;
            }
        }
    }
    printf("%d\n",dp[now][0]);
}

  

posted @ 2017-02-23 21:13  SfailSth  阅读(240)  评论(0编辑  收藏  举报