1. 程式人生 > >洛谷P1118 數字三角形【dfs】【STL】

洛谷P1118 數字三角形【dfs】【STL】

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 long
long 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】