首页 > 其他 > 详细

Little Kings - SGU 223(状态压缩)

时间:2015-10-04 11:06:52      阅读:208      评论:0      收藏:0      [点我收藏+]

题目大意:在一个N*N的棋盘上放置M个国王,已知国王会攻击与它相邻的8个格子,要求放置的额国王不能相互攻击,求放置的方式有多少种。

分析:用dp[row][state][nOne],表示本行状态state时候的放置国王nOne时候情况有多少种,状态转移也比较简单了.....

代码如下:

===================================================================================================================================

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;

const int MAXN = 1<<10;

bool G[MAXN][MAXN];
int bit[MAXN], cnt, N, M;
int one[MAXN];
long long dp[12][MAXN][107];

void DFS(int k, int state, int nOne)
{
    if(k >= N)
    {
        one[cnt] = nOne;
        bit[cnt++] = state;
        return ;
    }
    DFS(k+1, state, nOne);
    DFS(k+2, state|(1<<k), nOne+1);
}

int main()
{
    scanf("%d%d", &N, &M);

    DFS(0, 0, 0);

    for(int i=0; i<cnt; i++)
    for(int j=i; j<cnt; j++)
    {
        if((bit[i]&bit[j])+(bit[i]&(bit[j]<<1))+(bit[i]&(bit[j]>>1))==0)
            G[bit[i]][bit[j]] = G[bit[j]][bit[i]] = true;
    }

    dp[0][0][0] = 1;

    for(int i=1; i<=N; i++)
    for(int j=0; j<cnt; j++)
    for(int k=0; k<cnt; k++)
    {
        if(G[bit[j]][bit[k]])
        {
            for(int t=one[j]; t<=M; t++)
            {
                dp[i][j][t] += dp[i-1][k][t-one[j]];
            }
        }
    }

    long long ans=0;

    for(int i=0; i<cnt; i++)
        ans += dp[N][i][M];

    printf("%lld\n", ans);

    return 0;
}

 

Little Kings - SGU 223(状态压缩)

原文:http://www.cnblogs.com/liuxin13/p/4854318.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!