用状压DP计算手机上九宫格的解锁方案数
Posted wwwsealss
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用状压DP计算手机上九宫格的解锁方案数相关的知识,希望对你有一定的参考价值。
首先有两个限制条件:
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计算手机上九宫格的解锁方案数的主要内容,如果未能解决你的问题,请参考以下文章