码迷,mamicode.com
首页 > 其他好文 > 详细

状态压缩dp入门

时间:2015-02-11 14:21:45      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

poj1321 http://poj.org/problem?id=1321

我们可以把棋盘的每一行看做是一个状态,如果某一列放置了棋子,那么就标记为1,否则就标记为0.然后把它看成是一个二进制数,然后转为10进制数,就可以当做数组下标然后进行状态转移了

设dp[i][s] 为处理到第i行时,状态为s的方法数

那么我们枚举第i-1行的所有状态s

dp[i][s] += dp[i-1][s]; //表示第i行不放置棋子的方法数

dp[i][s|(1<<j)] += dp[i-1][s] //表示第i行第j列放置棋子的方法数   (前提是 chess[i][j]==‘#‘ && 状态s第j列没有放过棋子)

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 char chess[9][9];int dp[11][1<<8];
 4 int n,k;
 5 int main()
 6 {
 7     int i,j,s,ss;
 8     while(scanf("%d%d",&n,&k)!=EOF)
 9     {
10         int ans = 0;
11         if(n==-1) return 0;
12         memset(dp,0,sizeof(dp));
13         for(i=1; i<=n; ++i)
14         {
15             scanf("%s",chess[i]);
16         }
17         dp[0][0] = 1;
18         for(i=1; i<=n; ++i)
19             for(s=0; s<(1<<n); ++s)
20             {
21                 
22                 for(j=0; j<n; ++j)
23                     if(chess[i][j]==#&&((1<<j)&s)==0)
24                         dp[i][s|1<<j] += dp[i-1][s];//表示第i行第j列放置棋子的方法数  
25                 dp[i][s] += dp[i-1][s]; //表示第i行不放置棋子的方法数
26             }
27         ///for(j=1; j<=n; ++j)
28         for(s=0; s<(1<<n); ++s)
29         {
30             i = s;
31             int cnt = 0 ;
32             for(;i;i-= i&-i)//统计状态s有多少个1,表示放了多少个棋子
33                 cnt ++;
34             if(cnt==k)
35                 ans+= dp[n][s];
36         }
37         printf("%d\n",ans);
38     }
39     return 0;
40 }

 

状态压缩dp入门

标签:

原文地址:http://www.cnblogs.com/justPassBy/p/4285851.html

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