码迷,mamicode.com
首页 > 移动开发 > 详细

用状压DP计算手机上九宫格的解锁方案数

时间:2016-03-18 07:05:04      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

首先有两个限制条件:

1. 至少经过四个点。

2. 从一个点到另一个点,如果它们的连线上经过另外一点,如果这个点还没走过,那么必须经过,否则可以跳过这个中间点。

不熟悉限制条件的话可以自己去尝试一下~~~

状态数很少只有2^9,所以直接用状压DP搞起~~

dp[i][state]表示在状态state的情况下,最后停在节点i上的方案数,其中state是个二进制数,1表示这个位置的点已经过,0表示没有经过,那么状态转移方程是:

dp[j][state|(1<<j)]+=dp[i][state] 表示state状态下从i走到j~~~

枚举的过程中注意各种限制条件就好啦~~~

直接上代码:

int check[9][9];
int dp[10][600];

int main()
{
    memset(check, 0, sizeof(check));
    memset(dp, 0, sizeof(dp));
    check[0][8]=check[8][0]=4;
    check[0][2]=check[2][0]=1;
    check[3][5]=check[5][3]=4;
    check[6][8]=check[8][6]=7;
    check[2][6]=check[6][2]=4;
    check[0][6]=check[6][0]=3;
    check[1][7]=check[7][1]=4;
    check[2][8]=check[8][2]=5;
    for(int i=0;i<9;++i) dp[i][(1<<i)]=1;
    for(int i=1;i<(1<<9);++i)
        for(int j=0;j<9;++j)
            if(i&(1<<j))
                for(int k=0;k<9;++k)
                    if(!(i&(1<<k)))
                        if(!check[j][k]||(i&(1<<check[j][k])))
                            dp[k][i|(1<<k)]+=dp[j][i];
    int ans=0;
    for(int i=0;i<9;++i)
        for(int j=1;j<(1<<9);++j)
        {
            int k=j,cnt=0;
            while(k)
            {
                ++cnt;
                k=k&(k-1);
            }
            if(cnt>3) ans+=dp[i][j];
        }
    printf("%d\n",ans);
    return 0;
}

 

用状压DP计算手机上九宫格的解锁方案数

标签:

原文地址:http://www.cnblogs.com/wwwsealss/p/5290220.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!