棋盘放车问题

问题描述:

在n*n(n≤20)的方格棋盘上放置n个车,求使它们不能互相攻击的方案总数。

问题分析:车子的攻击是直线的上下和左右的。那么我们可以认为是一行一行扫描过来。有dp[i][j]。j表示排列状况

     但是根据24点游戏的经验。我们完全可以直接根据排列状况来划分状态。(状态本身就是答案。)

                   0001  是由 0000得来的。

                            0011  是由 0010 + 0001得来的。

    状态压缩的真正厉害之处不是以物体为刷层。而是以序列来刷层。并且一个循环过去。是从小到大有方向性的刷层。

    (也许我可以用2种方法来写24点游戏)。一般来说还是刷层的方法比较好。。去处法DP。

#include<stdio.h>
#include<string.h>
int dp[30000];
// 8个棋盘 130个 n范围是9个棋盘
int main()
{
    int n,i,j;
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        dp[0] = 1; //还没填 对于不摆当然是1啦。

        for(i=1; i<= (1<<n)-1;i++) //n个1,这一层是状态的扫描。
        {
            for(j=i;j>0;j -= (j&-j))
            {
                dp[i] += dp[i-(j&-j)];
        //这个dp 是由当前的数的位置(i-(j&-j))的不同而获得的值
            }
        }
        printf("%d\n",dp[(1<<n)-1]);
    }
    return 0;
}
View Code

相关文章:

  • 2022-12-23
  • 2022-01-23
  • 2021-06-13
  • 2021-12-02
  • 2022-01-23
  • 2022-12-23
猜你喜欢
  • 2021-12-02
  • 2021-12-22
  • 2021-06-21
  • 2021-11-16
  • 2021-12-18
  • 2022-12-23
相关资源
相似解决方案