第一次接觸狀壓DP

2022-05-15 07:46:31 字數 2470 閱讀 7714

*(另類的暴力)*

一般狀態數不多的時候就會開陣列,但是有的狀態並不好表示,於是,狀壓dp就產生了。

狀壓dp應該是分兩類的,一類是壓縮狀態,另一類是捨棄狀態。    我感覺初學狀壓dp難就難在二進位制運算的應用,了解二進位制運算子就顯得十分重要。

所以我們先看下表,如果有不會二進位制簡單應用的神犇請忽略...)

下面就可以看題了:

對於狀壓壓縮,入門題[usaco06nov]玉公尺田和corn fields[scoi2005]互不侵犯,思路基本上相同。

[usaco06nov]玉公尺田corn fields

我自己做了這兩個題有兩點體會,如下:

第一點(第一題):我們可以通過迴圈預處理出所有的狀態,再在動態規劃的過程中判斷狀態是否可行,方案數累加即可。

這樣來,動態規劃的方程就很好推出來了(初學者可能有點困難)。

f[ i ][ j ] 表示前i行,第i行狀態為j的方案數,j存的是狀態,用二進位制表示。

**如下:

#include#include

#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;}

[scoi2005]互不侵犯第二點(第二題):我們可以通過dfs搜尋出所有符合情況的方案記錄下來再進行動態規劃。

dfs過程中如果搜到行的盡頭,我們就儲存狀態再返回,否則就進行下一步搜尋。

搜尋分兩種狀態:1.當前格仔不放國王,搜尋下乙個格仔  2.當前格仔放國王,就得跳過下乙個格仔搜尋。(**中有特別注釋)

我們先不要管在列方向上的約束,只管每一行的國王不能放在一起,每一列的國王不能放在一起那是下面要考慮的問題。

當所有滿足條件的行的狀態都搜尋出來之後,就可以動態規了,中間剔除列上不符要求的狀態。

動態規劃方程也跟上題的差不多:

f[ i ][ j ] [ k ] 表示前 i 行 ,第 i 行狀態為j  總共選了k個國王的方案數。

#include#include

#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;

}

嗯,這道題是右上角的大佬教我的。2018-07-2819:17:14

第一次狀壓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...