這個題目的意思是給定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出發訪問剩餘的所有頂...