SCOI 2005 互不侵犯

洛谷 P1896 [SCOI2005]互不侵犯

洛谷傳送門數組

題目描述

在N×N的棋盤裏面放K個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各一個格子,共8個格子。spa

注:數據有增強(2018/4/25)code

輸入格式

只有一行,包含兩個數N,K ( 1 <=N <=9, 0 <= K <= N * N)get

輸出格式

所得的方案數io

輸入輸出樣例

輸入 #1複製class

輸出 #1複製變量

題解:

原諒我一開始看到題還覺得是爆搜。。。搜索

實際上是一道狀態壓縮的題目。二進制

蒟蒻本身一個比較大的進步就是把本身狀態設置對了...統計

設置:\(dp[i][j][k]\)爲第\(i\)行狀態爲\(j\)、已經用了\(k\)個國王時的方案數。

狀態壓縮大致有這麼幾步:設置狀態\(\rightarrow\)考慮轉移方式\(\rightarrow\)按轉移方式考慮預處理和判斷轉移條件\(\rightarrow\)開始轉移\(\rightarrow\)統計答案。

那麼咱們設置好狀態,開始考慮轉移方式:咱們發現,如果想從第\(i-1\)行開始轉移,轉移的條件一是當前和上一次的狀態,可是,這些狀態的改變必然還會改變國王的個數。也就是說,這數組的兩維是有聯繫的,是自變量和因變量的關係。因此咱們所以想到,既然是自變量和因變量的關係,咱們莫不如由此構建一個映射,存下來每一個狀態和每一個狀態須要的國王人數。這樣咱們轉移的時候就沒啥問題了。

如何預處理呢?咱們想到,咱們須要按行處理狀態,每一個狀態有放國王和不放國王兩種選擇。由於是預處理,咱們是確定不能用遞推和\(DP\)的(你想幹啥)

因此咱們考慮搜索。

一次搜索能夠處理出全部合法的行的方式。

這裏插一嘴,由於咱們已經把全部合法的行的方式都求出來了,因此咱們不必再把\(dp\)數組的第二維開那麼大,構建好映射關係以後,直接用\(cnt\)代替這個二進制狀態便可。(由於\(1-cnt\)的每一個數都對應着一個數組\(s[i]\)做爲狀態。)

而後再轉移的時候進行判斷是否合法就能夠。

轉移方程:
\[ dp[i][j][l]+=dp[i-1][k][l-num[j]] \]
這裏的\(k,j\)分別表示一種狀態。

代碼:

#include<cstdio>
#define int long long
using namespace std;
int n,K,cnt,ans;
int s[100],num[100];
int dp[10][100][110];
//dp[i][j][k]表示前i-1行放完,第i行狀態爲j、有k個國王時的方案數
//狀態0/1:0:國王攻擊不到;1:被國王佔領
void dfs(int pos,int st,int tot)
{
    if(pos>=n)
    {
        s[++cnt]=st;
        num[cnt]=tot;
        return;
    }
    dfs(pos+1,st,tot);
    dfs(pos+2,st+(1<<pos),tot+1);
}
signed main()
{
    scanf("%lld%lld",&n,&K);
    dfs(0,0,0);
    for(int i=1;i<=cnt;i++)
        dp[1][i][num[i]]=1;
    for(int i=2;i<=n;i++)
        for(int j=1;j<=cnt;j++)
            for(int k=1;k<=cnt;k++)
            {
                if(s[j]&s[k])
                    continue;
                else if(s[j]&(s[k]>>1))
                    continue;
                else if(s[j]&(s[k]<<1))
                    continue;
                else
                    for(int l=num[j];l<=K;l++)
                        dp[i][j][l]+=dp[i-1][k][l-num[j]];
            }
    ans=0;
    for(int i=0;i<=cnt;i++)
        ans+=dp[n][i][K];
    printf("%lld",ans);
    return 0;
}
相關文章
相關標籤/搜索