狀壓dp小記

2021-09-05 03:10:18 字數 3671 閱讀 8278

鋪磚

題意:現有nm的一塊地板,需要用12的磚塊去鋪滿,中間不能留有空隙。問這樣方案有多少種

#include

using namespace std;

typedef

long

long ll;

const

int maxn =

1<<11;

int n,m,state;

ll dp[15]

[maxn]

;//s1表示本行鋪磚的狀態,s2表示下一行鋪磚的狀態

voidf(

int i,

int s1,

int s2,

int d)

else

}else}}

intmain()

if(nswap

(n,m)

;//交換n,m列舉小的指數

state =

1

(dp,0,

sizeof

(dp));

dp[1]

[0]=

1;//初始化f(

1,0,

0,0)

;//預處理出第一行到第二行

for(

int i=

2;i<=n;

++i)}}

printf

("%lld\n"

,dp[n+1]

[0])

;//最終答案上面n行鋪滿,第n+1行未鋪。

}return0;

}

poj 2288

題意:給出n(n<13)個小島m條邊連線,每個小島有乙個權值wi,再給出一條哈夫曼路徑權值之和由三部分組成:

1)路徑上經過結點的權值之和,ans1 = sigma(wi)

2)路徑上相連線的兩個結點u,v ans2 = sigma(wuwv);

3)路徑上連通的三點a,b,c能形成乙個三角形, ans3 = sigma(wawb*c);

4)哈夫曼路徑的定義為從0到n-1不重複不遺漏的經過每乙個結點恰好一次。

5)以相反順序遍歷路徑相同的算同一條路徑。

求:1)哈夫曼路徑的最大值

2)最大值條件下的路徑數目

3)沒有輸出0 0

思路:狀壓dp,n位二進位制數,其中第i(0**:

#include

#include

#include

#include

using namespace std;

typedef

long

long ll;

const

int maxn =

1<<13;

int dp[maxn][13

][13]

;ll path[maxn][13

][13]

;int w[13]

;int g[13]

[13];

void

init()

intmain()

}for

(int i =

0; i < m;

++i)

if(n ==1)

init()

;for

(int i =

0; i < n;

++i)}}

int up =

1<< n;

for(

int state =

0; state < up;

++state)

if(tmp > dp[state|(1

<][j]

[k])

else

if(tmp == dp[state|(1

<][j]

[k])}}

}}int maxx =0;

int state =(1

<; ll cnt =0;

for(

int i =

0; i < n;

++i)

else

if(maxx == dp[state]

[i][j])}

}printf

("%d %lld\n"

,maxx,cnt/2)

;}return0;

}

poj 3254

題意:給出n*m的牧場,0表示土地不肥沃,1表示土地肥沃,且相鄰兩塊土地不能種植牧草,問其一共有多少種種植方案(什麼都不種植也算一種。)

#include

using namespace std;

const

int maxn =

1<<12;

const

int mod =

100000000

;int m,n;

int state[maxn]

;//可行狀態數

int up;

//狀態數上界

int dp[15]

[maxn];//

int cur[15]

;//記錄當前行狀態

inline bool check

(int x)

inline bool fit

(int x,

int i)

void

init()

}int

main()

}}for(

int i=

1;i<=up;

++i)

}for

(int i=

2;i<=m;

++i)}}

int ans =0;

for(

int i=

1;i<=up;

++i)

printf

("%d\n"

,ans);}

return0;

}

p1171 售貨員的難題

題意:某鄉有nn個村莊(1code:

#include

using namespace std;

typedef

long

long ll;

const

int inf =

0x3f3f3f3f

;const

int maxn =

1<<21;

int dp[maxn][25

];//當前狀態為i,到達目的結點j的路徑的最短路徑.

int a[25]

[25];

intmain()

}for

(int i=

0;i<=(1

<;++i)

} dp[1]

[0]=

0;int state =(1

<;for

(int i=

0;i<=state;

++i)}}

}int ans =

0x3f3f3f3f

;for

(int i=

1;i++i)

if(n==

1) ans =0;

printf

("%d\n"

,ans)

;return0;

}

狀壓dp 玉公尺田 狀壓dp

相關 強相關 327.玉公尺田 狀壓dp 小國王 狀壓dp 是井字形,本題是十字形。思路 狀態計算 時間複雜度 n 2 n 2n o n 22n 12 2 24n 2 n 2 n o n2 12 2 n 2n 2 n o n22n 12 224 看著妥妥超時,但是裡面合法狀態很少 依舊可以過 在此,...

狀壓dp學習

p2704 炮兵陣地 1038 裁玻璃 狀壓dp是一種非常暴力的做法,列舉所有可能的狀態,找到要求的最佳狀態,與一般dp不同,前一項與後一項有一些複雜的狀態關係。dp的引數 物品個數 行數等 當前狀態 上乙個狀態 將abc的有無表示成乙個8個狀態,列舉所有組,列舉上乙個狀態,得到當前狀態的最優解 i...

狀壓 博弈dp

傳送門 題目大意 遊戲的雙方能在 1 n 之間選擇乙個數加到sum上,每個數只能選擇一次。誰先將sum 變得 max 誰就贏了。現在問你,給定 n sum.先手是否能贏 兩方採取最優策略 n 20 max 300 思路 很容易發現n 很小,可以直接狀態壓縮。但是有乙個問題。直觀的想法是開二維陣列,這...