POJ 3187 穷举

题意:已知有N个数分别为1-N,如下图为4个数。相邻两两相加直至只剩下一个数,下图的结果就是16。

    3  1   2   4

         4   3   6

         7   9

        16

  现在反过来看,告诉你数的个数N和最终结果,问这N个数的初始序列是什么。求出字典序最小的初始序列。上图的初始序列也可以是3 2 1 4,但这不是字典序最小。

分析:这题用全排列的方式非常容易做。首先初始化数组为1-N,然后用STL提供的按字典序生成全排列的函数next_permutation即可枚举全排列。对于每一组数,通过计算可以知道它是否能得出已知结果。最先找到的那组数就是字典序最小的值。

 1 /*
 2 input:
 3 4 16
 4 output:
 5 3 1 2 4
 6 */
 7 #include <cstdio>
 8 #include <algorithm>
 9 
10 using namespace std;
11 
12 const int MAX_N = 10;
13 
14 //输入
15 int N, finalSum;
16 
17 int a[MAX_N][MAX_N];                //保存序列以及计算序列结果
18 
19 int calulate(){
20     //计算序列所得的最后和
21     for(int i = 1; i < N; i ++){
22         for(int j = 0; j < N - i; j ++){
23             a[i][j] = a[i - 1][j] + a[i - 1][j + 1];
24         }
25     }
26     return a[N - 1][0];
27 }
28 
29 void solve(){
30     //初始化序列
31     for(int i = 0; i < N; i ++)
32         a[0][i] = i + 1;
33     //按字典序枚举全排列
34     do{
35         int sum = calulate();
36         if(sum == finalSum){
37             printf("%d", a[0][0]);
38             for(int i = 1; i < N; i ++){
39                 printf(" %d", a[0][i]);
40             }
41             printf("\n");
42             break;
43         }
44     }while(next_permutation(a[0], a[0] + N));
45 
46 }
47 
48 int main(int argc, char const *argv[]){
49 
50     scanf("%d %d", &N, &finalSum);
51     solve();
52 
53     return 0;
54 }

 

posted @ 2014-03-15 09:54  7hat  阅读(298)  评论(0编辑  收藏  举报