poj 1037 動態規劃 計數,求排列布局

2021-06-04 23:52:09 字數 2146 閱讀 3115

這道題,黑書上p257有解題的分析,之前沒看明白~~,網上搜了一大堆

看了這兩位大牛的報告

題目的大意就是一些裝飾欄,編號為1,2,3,...,n,他們的排列要遵循每個柵欄的編號要麼同大於相鄰的柵欄編號(a(i)>a(i-1), a(i) > a(i+1)),要麼同小於相鄰的柵欄編號(a(i) < a(i-1), a(i) < a(i+1))。按這種方式的每種排列按字典序排放,每種排列有乙個編號,從小到大,現在給出柵欄的個數,排列的序號,要你求出這個序號對應的排列布局。

動態規劃+計數

看了黑書上的感覺前面的敘述講得很模糊甚至感覺不對。。。。就後面的結論是對的,但是他又沒解釋那個g[n][t].up = sum(g[n-1][i].dowm)(t<=i<=n-1),為啥是i是從t開始的,還是看了某大牛的才明白,,,就是個對應關係,不考慮絕對高度,只考慮相對的高度

比如在1,2,3,4,5裡面選了3,那麼剩下1,2,4,5,因為只考慮相對高度,所以可以對應為1,2,3,4所以後面的n-1長從3開始

設dp[i][j][0]表示以i開頭,長度為j,頭兩塊板子是上公升的排列數

dp[i][j][1]表示i開頭,長度為j,頭兩塊板子是下降的排列數

那麼dp[i][j][0] = sum(dp[k][j-1][1])     i =< k <= j-1

dp[i][j][1] = sum(dp[k][j-1][0])   1<=k dp[1][1][0] = dp[1][1][1] = 1

這樣就求出了dp[i][n][1]和dp[i][n][0]

那後看序號c出現在哪個段中這些段為排列為

dp[1][n][1], dp[1][n][0]

dp[2][n][1], dp[2][n][0]

.....

dp[n][n][1], dp[n][n][0]

若c出現在dp[i][n][1], dp[i][n][0]這個段中

求出c在這個段中的第幾個c = c - sum   sum = (dp[1][n][1] + dp[1][n][0] + ... + dp[i-1][n][1] + dp[i-1][n][0])

然後當c <= dp[i][n][1]說明c出現在dp[i][n][1]這個段裡面, 否則出現在dp[i][n][0]這個段裡面

因為dp[i][n][0] = sum(dp[k][n-1][1])     i =< k <= n-1,;

dp[i][n][1] = sum(dp[k][n-1][1])     1=< k  < i

所以按照字典序,從小到大列舉k,從1到0的順序列舉下降和上公升

儲存每個i

由於每次儲存的i是經過之前的那種1,2,3,4,5選出3後,剩下1,2,4,5對應於1,2,3,4的那種方法所確定的

所以輸出要返回對映為1---n的數

暴力搜尋。。。。

從1-n遍歷j,沒有輸出就ans[i]--,當ans[i]==0表示這個數是j,標記j已經被輸出,下次遍歷就不算進去

#include #include #include #include using namespace std;

const int maxn = 25;

long long dp[maxn][maxn][2], c;

int ans[maxn];
bool visited[maxn];

int k, n;

void init();

void solve();

void output();

int main()

return 0;

}void init()

}}void solve()

sum += (dp[i][tn][0] + dp[i][tn][1]);

}if(c <= dp[cur][tn][1])

flag = true;

else

tn--;

while(tn > 0)

c -= dp[i][tn][0];}}

else

c -= dp[i][tn][1];}}

tn--;

flag = !flag;

}}void output()}}

}printf("\n");

}

poj 1037 動態規劃 字典序第k大

題目大意 給定n個數字,規定一種 cute 排序 序列中的數字大小為嚴格的波浪形,即 a 0 a 1 a 2 a 3 或者 a 0 a 1 a 2 a 3 對於n個數字來說,可以構成多個cute序列,這些序列按照字典序進行排序,求出第k個序列。題目分析 一 求字典序的第i個排列 直接一位一位列舉答案...

BZOJ1037動態規劃

資料範圍很小,可以用4維儲存下前i個男孩j個女孩,從這一位往前的所有點中男 女的差最大為x,女 男為y的方案數 主動遞推 f i 1 j x 1 max y 1 0 f i j x y f i j 1 max x 1 0 y 1 f i j x y 最後答案為 sigma x sigma y f n...

poj1037 dp 排列計數

今天學習dp 看的是北大培訓的課件 看到了這道題 開始看的時候 就算知道是dp 也不知道怎麼去寫 後面看了ac 直接寫思路 c i k down 表示的是前i根木頭中 以k打頭陣的down總數 c i k up 表示的是 前i根木頭中 以k打頭陣的up總數 再寫這道題時 首先要知道怎麼去排列計數 直...