基礎知識位運算:
1.& 與 x&y表示x和y在二進位制下滿足,每一位有0則0,否則為1的標準進行按位與;
2. | 或 x|y表示在二進位制下每一位按照全0則0,否則為1的標準按位或;
3. ^ 異或 x^y 「同為假,異為真」;
4.判斷乙個十進位制數x在二進位制下第i為是否為1 if ( ( ( 1 << ( i - 1 ) ) & x ) > 0)
5.將乙個x進製第i位更換1 x=x|1<
6.把乙個數字二進位制下最靠右的第乙個1去掉 x=x&(x-1)
題目描述:
注意到n,m的範圍比較小,我們要考慮狀壓了,直接搜尋的話:比如我們搜尋每一列,需要記錄上一行每個點的狀態,使用陣列的顯然存不下,所以我們轉變一下思路,採用狀壓+dfs,其實和狀壓dp差不多;
具體怎麼做呢,我們發現,對於每一列,他的狀態只能由上一列的狀態轉移而來,所以我們可以用乙個十進位制數表示當前列的狀態;
dp【i】【s】表示對於放置第i列,第i-1列對他
的狀態是s時的方案數;
對於搜尋,我們不妨將1*2和2*1分開來做,對於第j行,如果j+1可放並且j可放,那我們考慮放乙個2*1的矩陣,那對下一列i+1的影響仍然為ne了;
如果當前j可放,我們也可以考慮乙個1*2的矩陣,那麼對下一列的影響就是ne|(1<
dp[i][s]=∑dp[i-1][k]每乙個k可以通過填放成為s;
對於搜尋,我們只需要對於每一列i,搜尋每一行,並且記錄其對下一列的狀態為ne,判斷狀態是否合法,然後進行深搜就可以了;
#includeusingview codenamespace
std;
long
long n,m,dp[13][5000
];template
inline void read(t &x)
while(isdigit(ch))
x*=f;
}inline
void dfs(int i,int j,int s,int
ne)
//因為是從第0行開始搜的
if(((1
<0)
if(((1
<0)
if(j+1
1<0&&((1
<
}int
main()
cout
<1][0];//
對m+1列的影響為0表示第m列放滿
return0;
}
感覺說的好不清楚;
狀壓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...