題目大意
給定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...