UVA 6625 狀態壓縮dp

2021-07-05 00:06:37 字數 1634 閱讀 1342

這個題目的意思是給定k,n( k,n<=7)

並給定k行每行有幾個連續的空格,所有的行左對齊,每一行最多7個,下面的行的空格數<=上面相鄰行的空格數

給定乙個填數字的規則,當對於任意位置i,j ,  num[ i ][ j ] > num[ i-1 ][ j ] && num[ i ][ j ] >= num[ i ][ j-1 ] 問有(只用數字1->n)有多少種填滿空格的方案。

解:對於直接定義前每一行被填成了什麼數,當前走到了第幾行,這樣的狀態狀態總數為7*7^7,狀態轉移為sum(7 - numi),空間時間都受不了。

那麼,對於本題目還有乙個性質,對於任意的一列其數值成增長趨勢,那麼所有列的狀態最多不超過 2^7(可以想一想為什麼)

那麼定義d[ i ][ s ]代表走到第i列,前一列的狀態是s( s為二進位制數最大為(1<<7)-1 , 對於任意位置該位置為1 代表選了i, 0代表沒選,1的個數即和該列空格數相同)

那麼狀態轉移就很明顯了,不多說了,可以按1的個數,將2^n個狀態分到不同陣列裡,來優化狀態轉移。

每個狀態的最大轉移為 c(7,3) = 7*6*5/3/2= 35;

最大代價一定比 (7 * 2^7 * 35 = 31360) 小

//#pragma comment(linker, "/stack:1024000000,1024000000")

#include #include #include #include #include #include #include #include #include #include #include #include #include #define all(a) a.begin(), a.end()

#define clr(a, x) memset(a, x, sizeof a)

#define fst first

#define snd second

#define pb push_back

#define ls (rt<<1)

#define rs (ls|1)

#define lson l, mid, ls

#define rson mid+1, r, rs

#define rep(i,n) for(int i=0;i<(int)n;i++)

#define rep1(i,x,y) for(int i=x;i<=(int)y;i++)

#define sqr(x) ((x)*(x))

using namespace std;

typedef long long ll;

typedef long long ll;

typedef pairpii;

const int n = 10;

const int m = 1<<7;

int bitcount(int x)

vectorg[n];

int a[n],l[n],k,n;

void init()

}int c1[n],c2[n],t1,t2;

inline int judge(int s,int ps)

{ t1 = 0, t2 = 0;

for(int i=0; i=1; i--)

{int p = l[i-1];

for(int j=0; j

,

UVa 10944 狀態壓縮DP

第一道狀態壓縮dp題,感覺要好好學習這種思維方式 首先設l的位置為 pointx 0 pointy 0 其他節點的位置為 pointx i pointy i 然後求出各個節點之間的距離dis i j max 我們用乙個n位2進製數 bn 1,b0 表示堅果收集情況的組合狀態 其中bi 0表示第i 1...

uva11795 簡單狀態壓縮DP

一看到n 16就想到狀態壓縮dp了,而且只要儲存這個狀態就行了 轉移時也用狀態壓縮的轉移方法,比較兩個二進位制數,就能知道能否從已知狀態轉移到需要的狀態 開始沒看到題目給的就是二進位制數,自己還轉換成了二進位制 還有要記得用longlong 不能因為這個wa 還有位運算還不是很熟悉,可以用異或來去掉...

狀態壓縮DP

首先,我們以一道狀壓經典題tsp來引入。tsp問題 一張圖上有n個點,給定相應的鄰接矩陣,需要求出從0號節點出發,經過且只經過每個頂點一次,最後仍回到0號節點的最小邊權。思路 假設現在已訪問過的頂點集合 起點0當作還未訪問過的頂點 為s,當前所在頂點為v,用dp s v 表示從v出發訪問剩餘的所有頂...