UVa Problem 10128 Queue (隊伍)

來源:互聯網
上載者:User
// Queue (隊伍)// PC/UVa IDs: 110803/10128, Popularity: B, Success rate: high Level: 2// Verdict: Accepted // Submission Date: 2011-07-08// UVa Run Time: 0.040s//// 著作權(C)2011,邱秋。metaphysis # yeah dot net//// 回溯法明顯是太慢,效率不可接受,雖然本題歸於回溯法一節,但是用回溯的方法效率太低(被// Programming Challenges 誤導了)。可以考慮動態規劃。動態規劃可以這樣考慮:假設當前已有 n 個// 人排列成隊伍,新增的人是最矮的,則可以得到以下關係://// perm[n][p][r] = perm[n - 1][p][r] * (n - 2) + perm[n - 1][p - 1][r] +// perm[n - 1][p][r - 1]//// (1)perm[n - 1][p][r] * (n - 2):新增最矮的人可以放在排列好的 n - 1 個人形成的左邊剛好//     p 人,右邊剛好 r 人視野不被擋住的隊列的中間,因為有 n - 2 個空,所以共有 perm[n - 1]//     [p][r] * (n - 2) 種安排方法。//// (2)perm[n - 1][p - 1][r]:由於該人比所有人矮,故可以直接放在隊首。//// (3)perm[n - 1][p][r - 1]:由於該人比所有人矮,故可以直接放在隊尾。#include <iostream>#include <cstring>using namespace std;#define NMAX 14long long perm[NMAX][NMAX][NMAX];// 解空間。long long solution_counter;// 解的個數。// 判讀該排列是否符合條件。bool check(int number[], int n, int p, int r){int tp, tr, left, right;tp = tr = 1;left = number[0];right = number[n - 1];for (int i = 1, j = n - 2; i <= n - 1 && j >= 0; i++, j--){if (left < number[i]){tp++;left = number[i];}if (right < number[j]){tr++;right = number[j];}}return tp == p && tr == r;}// 構建排列的候選元素。void construct_candidates(int number[], int k, int n, int c[], int *ncandidates){bool in_perm[NMAX];memset(in_perm, false, sizeof(in_perm));for (int i = 0; i < k; i++)in_perm[number[i] - 1] = true;*ncandidates = 0;for (int i = 1; i <= n; i++)if (in_perm[i - 1] == false)c[(*ncandidates)++] = i;}// 回溯法構建所有排列。void backtract(int number[], int k, int n, int p, int r){int c[NMAX];int candidates;if (k == n){if (check(number, n, p, r))solution_counter++;}else{construct_candidates(number, k, n, c, &candidates);for (int i = 0; i < candidates; i++){number[k] = c[i];backtract(number, k + 1, n, p, r);}}}// 回溯法解題,效率低,可考慮先將解空間表示成數組,然後根據具體資料直接輸出結果。long long permutation(int n, int p, int r){int number[NMAX];solution_counter = 0;backtract(number, 0, n, p, r);return solution_counter;}// 動態規劃,實際上是自下而上計算總方案數。long long dynamic_programming(void){perm[1][1][1] = 1;for (int n = 2; n < NMAX; n++)for (int p = 1; p < NMAX; p++)for (int r = 1; r < NMAX; r++)perm[n][p][r] =perm[n - 1][p][r] * (n - 2) + perm[n - 1][p - 1][r] + perm[n - 1][p][r - 1];}int main(int ac, char *av[]){int t, n, p, r;// 動態規劃解題。dynamic_programming();// 迴圈讀入測試資料直到結束。cin >> t;while (t--){// 讀入資料,計算滿足條件的組合。輸出。cin >> n >> p >> r;cout << perm[n][p][r] << endl;}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.