hdu2553 N皇后问题【二进制状态压缩基础】

rt,二进制压缩的入门题,依旧卡了一个多小时,还不算之前看的那一遍orz

本题要求行列两个斜线都不能多于一个,就算是一行一行遍历,也需要考虑状态的转移方法及记录转移的方法,那么,二进制华丽丽的出场啦~~当前位有就是1,没有就是0,这点是毋庸置疑的,那如何用上一状态表示下一可能的状态呢?

col表示列,fir表示左对角线,sec表示右对角线,三个数字作为参数代入递归函数,那么下一步能去的集合是((~(col|fir|sec))&high),依次取当前状态的最低位的方法是(canput)&(-canput),(负数是取反加一,再与原数取与,那么不就剩下了最低位嘛,之前学树状数组的时候就没有想到啊),递归再回溯,答案出现

优雅的递归~

/**************
hdu2553
2016.1.4
936MS 1412K 494 B GCC
*************/
#include<stdio.h>
int n,high,ans;
void dfs(int col,int fir,int sec)
{
    if(col==high){ans++;return;}
    int canput=((~(col|fir|sec))&high);
    while(canput)
    {
        int lowbit=(canput)&(-canput);
        dfs((col|lowbit),((lowbit|fir)>>1),(((lowbit|sec)<<1)&high));
        canput&=(~lowbit);
    }
}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        ans=0;
        high=(1<<n)-1;
        dfs(0,0,0);
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(压缩,递归,二进制,dp)