bzoj 1087 互不侵犯King

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1087

题解:
  刚开始光想着爆搜、打表,观摩大犇们的博客,才薛习了正解:状态压缩DP

  对于每一格,只有放国王或者不放国王两种可能,所以一行的状态可以表示为一个01串,可以想到压缩成一个十进制数存储,计算出所有可能的状态并编号,然后将互相矛盾的状态标记出来

  之后开始DP,f[i][j][k]表示第i行,第j种状态,放k个棋子的状态数

  四层循环,枚举行数i、状态数j、放的国王的个数l、上一行的状态m

  当满足两行的状态不矛盾,并且两种状态的国王数不超过l时,状态转移方程:
  f[i][j][l]+=f[i-1][m][l-j状态的国王数]

  最后,将f[n][1...状态总数][k]加起来得到结果

 1 #include<cstdio>
 2 #define MAXN 100
 3 int n,k,num_of_status,status[MAXN],status_sum[MAXN];//num_of_status记录状态总数,status记录十进制压缩后的状态,status_sum记录某种状态放了几个国王
 4 long long ans,f[MAXN]/*行号*/[MAXN]/*状态编号*/[MAXN*10]/*放的国王数*/;
 5 bool status_can[MAXN][MAXN];//某两种状态是否矛盾
 6 void dfs(int x,int y,int z)//计算一行中所有状态,表示这一行放x个棋子,用了y个格子,z表示十进制压缩后的状态
 7 {
 8     status[++num_of_status]=z;
 9     status_sum[num_of_status]=x;
10     if(x>=(n+1)/2||x>=k)return;//已经没有足够的空间放国王或者国王已经放完了
11     for(int i=y+2;i<=n;i++)dfs(x+1,i,z+(1<<(i-1)));
12 }
13 void get_can()
14 {
15     for(int i=1;i<=num_of_status;i++)
16     {
17         for(int j=1;j<=num_of_status;j++)
18         {
19             if(!((status[i]&status[j])||((status[i]>>1)&status[j])||(status[i]&(status[j]>>1))))status_can[i][j]=status_can[j][i]=true;//注意左下和右下也不能放国王,所以还要将这一行左移一位或者右移一位判断
20         }
21     }
22     for(int i=1;i<=num_of_status;i++)f[1][i][status_sum[i]]=1;//初始化第一行的状态
23 }
24 int main()
25 {
26     scanf("%d%d",&n,&k);
27     dfs(0,-1,0);
28     get_can();
29     for(int i=2;i<=n;i++)
30     {
31         for(int j=1;j<=num_of_status;j++)
32         {
33             for(int l=0;l<=k;l++)
34             {
35                 if(status_sum[j]>l)continue;
36                 for(int m=1;m<=num_of_status;m++)
37                 {
38                     if(status_can[m][j]&&status_sum[j]+status_sum[m]<=l)
39                     {
40                         f[i][j][l]+=f[i-1][m][l-status_sum[j]];
41                     }
42                 }
43             }
44         }
45     }
46     for(int i=1;i<=num_of_status;i++)ans+=f[n][i][k];
47     printf("%lld\n",ans);
48     return 0;
49 }

 

posted @ 2016-10-24 22:22  xqmmcqs  阅读(438)  评论(0编辑  收藏  举报