傳送門
這是一道狀壓dp的經典例題
題目讓輸出所有可能的方案數
很顯然 這是一道動態規劃了
由於國王放置的位置有一定的限制 所以我們要在狀態轉移的過程中增加一維來儲存狀態
我們這一道題假設f[i][j][k] 意思是在前i行一共放置了j個國王 第i行國王放置的狀態是k 儲存的值是方案數
首先 我們可以先預處理出左右合法的每行的狀態。。。(有點繞
就是說針對單獨的一行 會有那些合法的狀態 使得相鄰的兩個格仔最多只能放置乙個國王 沒有相鄰的國王
然後我們開始dp
我們分別列舉i k s
i是當前列舉到第幾行
k是第i行的狀態 編號
s是第i-1行的狀態編號
然後我們還要判斷一下
上下不能相等,對角線不能相等
這些條件都滿足之後 我們就可以列舉第i行國王的個數 並從上一行的狀態累加到當前狀態
最後我們把最後一行 放滿ss個國王 的不同狀態的f陣列的值累加起來就是總的方案數
進行位運算的時候還要注意一點
就是一定要多加括號!!!
//p1896 [scoi2005]互不侵犯
#include#define ll long long
using
namespace
std;
int p[300
];int num[300];//
記錄每一種狀態有多少個1
ll f[10][90][300
];int
main()
}
} f[
0][0][1]=1;//
什麼都不放的方案數是1 初始化
for(int i=1;i<=n;i++)
for(int k=1;k<=cnt;k++)
for(int s=1;s<=cnt;s++)
if((p[k]&p[s])==0)//
沒有上下攻擊
if(((p[k]>>1)&p[s])==0
)
if(((p[s]>>1)&p[k])==0
)
long
long ans=0
;
for(int i=1;i<=cnt;i++)
ans+=f[n][ss][i];
cout
return0;
}
P1896 SCOI2005 互不侵犯
p1896 scoi2005 互不侵犯 資料不大,時間複雜度很高也差不多能過。使用狀壓dp dp i j k 表示到第i行,狀態為j,選了k個人 然後就是轉移,轉移的難點就是快速判斷 判斷的話,我們整體考慮。然後乙個狀態是否有相鄰的國王。用它本身按位與它本身右移 左移 若結果為0,則說明無相鄰的國王...
P1896 SCOI2005 互不侵犯
首先,養成乙個思路 資料這麼小?狀壓dp!然後翻題解可以這麼定義狀態 定義 dp i j k 為前 i 行中,第 i 行狀態為 j 前 i 行已放置 k 個國王的方案數。顯然一行的狀態只與前一行的有關,所以只需要記錄一行的狀態。但是一行的狀態好像很難存啊!難道複製乙個陣列進去嗎?其實,對於每乙個點,...
P1896 SCOI2005 互不侵犯
在n n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔。注 資料有加強 2018 4 25 只有一行,包含兩個數n,k 1 n 9,0 k n n 所得的方案數 輸入樣例 1 複製3 2 輸出樣例 1 複製...