*(另類的暴力)*
一般狀態數不多的時候就會開陣列,但是有的狀態並不好表示,於是,狀壓dp就產生了。
狀壓dp應該是分兩類的,一類是壓縮狀態,另一類是捨棄狀態。 我感覺初學狀壓dp難就難在二進位制運算的應用,了解二進位制運算子就顯得十分重要。
所以我們先看下表,如果有不會二進位制簡單應用的神犇請忽略...)
下面就可以看題了:
對於狀壓壓縮,入門題[usaco06nov]玉公尺田和corn fields[scoi2005]互不侵犯,思路基本上相同。
[usaco06nov]玉公尺田corn fields
我自己做了這兩個題有兩點體會,如下:
第一點(第一題):我們可以通過迴圈預處理出所有的狀態,再在動態規劃的過程中判斷狀態是否可行,方案數累加即可。
這樣來,動態規劃的方程就很好推出來了(初學者可能有點困難)。
f[ i ][ j ] 表示前i行,第i行狀態為j的方案數,j存的是狀態,用二進位制表示。
**如下:
#include#include[scoi2005]互不侵犯第二點(第二題):我們可以通過dfs搜尋出所有符合情況的方案記錄下來再進行動態規劃。#include
#include
#include
#include
using
namespace std;//
前 i 行
//當前行 狀態為j的方案數
int n,m,a[15][15],g[1
<<12],f[15][1
<<12],mod=1e8;
int check(int
x)int
main()}}
int ans=0
;
for(int i=0;i
ans+=f[n][i],ans%=mod;
printf("%d
",ans%mod);
return
0;}
dfs過程中如果搜到行的盡頭,我們就儲存狀態再返回,否則就進行下一步搜尋。
搜尋分兩種狀態:1.當前格仔不放國王,搜尋下乙個格仔 2.當前格仔放國王,就得跳過下乙個格仔搜尋。(**中有特別注釋)
我們先不要管在列方向上的約束,只管每一行的國王不能放在一起,每一列的國王不能放在一起那是下面要考慮的問題。
當所有滿足條件的行的狀態都搜尋出來之後,就可以動態規了,中間剔除列上不符要求的狀態。
動態規劃方程也跟上題的差不多:
f[ i ][ j ] [ k ] 表示前 i 行 ,第 i 行狀態為j 總共選了k個國王的方案數。
#include#include嗯,這道題是右上角的大佬教我的。2018-07-2819:17:14#include
#include
#include
#define ll long long int
using
namespace
std;
ll n,t,top,sum[
2000],zt[2000],f[20][1000][300],ans;//
位置 狀態 選了幾個
void
dfs(ll z,ll s,ll ci)
dfs(z,s,ci+1);//
不選 dfs(z+(1
<1,ci+2);//選}
intmain()
}for(ll i=1;i<=top;i++)
ans+=f[n][i][t];
printf(
"%lld
",ans);
return0;
}
第一次狀壓DP 售貨員問題
嘛 tsp問題,模擬退火感覺好複雜。於是就各種找狀壓dp的 經過個人修改與綜合,現加如下修改注釋版本。另,狀壓dp如果狀態太多 可能會mle 用 f i s 表示當前到達 i 號點,狀態為 s 的最短路,最終我們只需在所有的 f i all map i 1 中找乙個最大值即可,all為全為1的01序...
第一次接觸ruby
part one afile file.new e calog.cfu w afile.puts rtwe calllog configuration file afile.puts rerew 2.0 calog afile.puts 日誌的根路徑 afile.puts base path e l...
第一次接觸ubuntu
第一次接觸ubuntu好激動 1.進入 退出命令列介面 alt ctrl f1 進入命令列介面 alt ctrl f7 退出命令列介面 2.安裝wine sudo apt get install wine使用 終端命令就是 wine 舉個例子,你現在要執行魔獸,然後你的魔獸的資料夾的位置是 home...