題面:
大意:在n×n的棋盤裡面放k個國王,使他們互不攻擊,共有多少種擺放方案。國王能攻擊到它上下左右,以及左上左下右上右下八個方向上附近的各乙個格仔,共8個格仔。
狀壓dp
用二進位制表示當前狀態。
1表示有,0表示無。
那麼這個題的f[ i ][ j ][ w ]表示在第 i 行,狀態為 j ,用了 w 個國王。
方程見**。
其中bitset為二進位制數字。
a.count()表示二進位制數中有多少個1。
vis[ ]陣列為符合條件的一行的狀態。
**如下:
#include#define int long long#define rr register
using
namespace
std;
int n,m,ans=0
;bool vis[1
<<9
];int f[10][1
<<9][90],g[1
<<9
];signed main()
for(rr int i=2;i<=n;i++)
for(rr int j=0;j<(1
<)
if(vis[j])
for(rr int k=0;k<(1
?if(vis[k] && !(j&(k<<1)) && !(j&(k>>1)) && !(j&k))
for(rr int w=0;w+g[k]<=m;w++)
f[i][k][w+g[k]]+=f[i-1
][j][w];
for(rr int i=0;i<(1
printf(
"%lld\n
",ans);
//system("pause");
return0;
}
因為資料加強,記得開 long long。
狀壓dp題解
實現 includeconst int maxn 1 20 1 typedef long long ll ll f maxn a 25 a x 記錄第x行的障礙狀態 int lowbit int x int main f 0 1 乙個也不放也是一種方案 int maxs 1 判斷當前狀態下狀態的1的...
題解 星空 狀壓DP
這道題思維難度非常高,有很多處理的小技巧,並且 也有很多細節 這道題是一種序列的區間操作,我們都知道,區間操作比較麻煩,所以我們要想辦法將區間操作轉換成單點修改 這時,我們想到了差分,假如我們對乙個序列進行操作,這時乙個序列裡的相對狀態不會變只有兩端改變,換句話說就是這個序列的差分並不會發生改變,只...
題解 Vjestica (狀壓DP)
有n個字元合集,求其字首樹的最少結點個數。資料範圍 n 16,1 m 1000000 字元個數 首先看到 n 16 可知,這道題是狀壓dp或者暴力 狀態是什麼?因為是n的資料範圍小,n為字元合集個數,所以狀態是 n個字元合集的整體 的選擇情況,這裡用s表示,二進位制範圍為 1 11111111111...