洛谷P1118 數字三角形【dfs】【STL】
阿新 • • 發佈:2019-02-08
ace ret ron == name https set blank 鏈接
題目鏈接:https://www.luogu.org/problemnew/show/P1118
題意:
1~n的一個排列,相鄰的兩項加起來得到下一行。
現在給定最後一行的數字,問最初的1~n的排列是什麽。
思路:
next_permutation大法好。但是要註意剪枝。
首先要發現最後一行這個數系數的規律是一個楊輝三角。
先處理出這個系數。
然後排列。
如果我們在加到前i項的時候發現他已經比結果大了,那麽後面不管怎麽排列都是沒有用的,要跳過。
怎麽跳過呢,這裏還挺tricky的【要學會!】
用sort對後面幾個數從大到小排序就行了,因為本身next_permutation就是按照“字典序”來排的
這裏要註意用的是do...while【竟然這年頭還真有用do...while的】
因為不然第一個1234....n這個排列沒有被考慮到。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<map> 4 #include<set> 5 #include<iostream> 6 #include<cstring> 7 #include<algorithm> 8 #include<vector> 9 #include<queue> 10 11 using namespace std; 12 typedef longlong LL; 13 typedef pair<int, int> pr; 14 15 int n, sum; 16 int num[15]; 17 int xishu[15][15]; 18 19 bool cmp(int a, int b) 20 { 21 return a > b; 22 } 23 24 int main() 25 { 26 // LL res = 1; 27 // for(int i = 1; i <= 12; i++){ 28 // res *= i; 29 // } 30 // printf("%lld\n", res);31 scanf("%d%d", &n, &sum); 32 for(int i = 1; i <= n; i++){ 33 num[i] = i; 34 } 35 xishu[1][1] = 1; 36 for(int i = 2; i <= n; i++){ 37 for(int j = 1; j <= i; j++){ 38 xishu[i][j] = xishu[i - 1][j - 1] + xishu[i - 1][j]; 39 } 40 } 41 42 do{ 43 int ans = 0; 44 bool flag = true; 45 for(int i = 1; i <= n; i++){ 46 ans += xishu[n][i] * num[i]; 47 if(ans > sum){ 48 flag = false; 49 sort(num + i, num + 1 + n, cmp); 50 break; 51 } 52 } 53 if(ans == sum && flag){ 54 printf("%d", num[1]); 55 for(int i = 2; i <= n; i++){ 56 printf(" %d", num[i]); 57 } 58 printf("\n"); 59 break; 60 } 61 }while(next_permutation(num + 1, num + 1 + n)); 62 63 return 0; 64 }
洛谷P1118 數字三角形【dfs】【STL】