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

2021-09-08 22:20:45 字數 1743 閱讀 1844

題目大意

給定n個數字,規定一種 cute 排序:序列中的數字大小為嚴格的波浪形,即 a[0] > a[1] < a[2] > a[3] < .... 或者 a[0] < a[1] > a[2] < a[3] .....。對於n個數字來說,可以構成多個cute序列,這些序列按照字典序進行排序,求出第k個序列。

題目分析

一、求字典序的第i個排列

直接一位一位列舉答案!從前到後列舉求得每一位:列舉一位時,計算在這樣的字首下,後面的總的排列數。如果嚴格小於總編號,則該位偏小,換更大的數,同時更新總編號;若大於等於,則該位恰好,列舉下一位,總編號不用更新。

二、使用動態規劃

for (int k = i; k <= m - 1; k++)

for (int k = 1; k < i; k++)

實現 (c++)

#define _crt_secure_no_warnings

#include#include#include#includeusing namespace std;

#define max_col_num 22

long long int up[max_col_num][max_col_num];

long long int down[max_col_num][max_col_num];

int main()

for (int k = 1; k < i; k++)

} }while (t--)

int result[max_col_num]; //存放最後求出的序列

int n = n;

long long int left = c;

//字典序第k大的序列

int next_dir = 2; //下一次選用的首數字和第二個數字構成上公升還是下降序列,由之前序列的趨勢決定

//0, 下降; 1上公升; 2 both

//開始設為2,表示總序列的第乙個和第二個之間的關係不明確

while (n >= 1)

else

}if (next_dir == 1 && candidates[k] < result[n-n-1])

else

}if (next_dir == 2)

else

}k++;

}if (k > n)

k = n;

result[n - n] = candidates[k];

next_dir = ! next_dir; //波浪形陣列,方向取反

//當選擇出來第乙個數字之後,可以根據 left (剩餘的序號)以及 down[n][k](以選擇出來的數字為開頭的下降序列的個數 ) 決定

//如果 剩餘的序號 小於等於 以選擇出來的數字為開頭的下降序列總數,則說明 第乙個數字和第二個數字為下降,之後的next_dir 為上公升

//否則,為下降

if (n == n)

}//從候選陣列中刪除已經選擇出來的那個數

candidates.erase(candidates.begin() + k);

n --;

} for (int i = 0; i < n; i++)

printf("\n");

} return 0;

}

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

這道題,黑書上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 按...

字典序的第K小數字

給定整數 n 和 k,找到 1 到 n 中字典序第 k 小的數字。1 k n 109。n 10時,字典序 1,10,2,3,4,5,6.可以把這n個數字看成字典樹,那麼每乙個字首都代表乙個數字,其中每個節點有10個兒子,0 9.那麼字典樹的先序遍歷的第k個就是答案。所以得到了乙個o k 的做法。這類...

UVa 1262 第k字典序 Password

題意 給出兩個6行5列的字母矩陣,乙個密碼滿足 密碼的第i個字母在兩個字母矩陣的第i列均出現。然後找出字典序為k的密碼,如果不存在輸出no 分析 我們先統計分別在每一列均在兩個矩陣出現的字母,然後從小到大排好序。對於第乙個樣例來說,我們得到acdw bop gmox ap gsu 則一共有4 3 4...