• POJ 3187 杨辉三角+枚举排列 好题


    如果给出一个由1~n组成的序列,我们可以每相邻2个数求和,得到一个新的序列,不断重复,最后得到一个数sum,

    现在输入n,sum,要求输出一个这样的排列,如果有多种情况,输出字典序最小的那一个。

    刚开始我是直接搜,tle了

    然后就开始找最初的序列和最终的和有什么关系

    因为最终的和sum一定是等于若干个a[1],若干个a[2],...,若干个a[n]的和

    即sum=p1*a1+p2*a2+...+pn*an

    所以我们只要求出数组a的系数,n个p即可。

    然后发现,和杨辉三角有很大的关系。

    如果杨辉三角的行数从1开始算的话,

    对于某一个1~n的排列得到sum,就需要有n个系数p,发现,这n个系数就刚好是杨辉三角的第n行。

    所以对于等式:sum=p1*a1+p2*a2+...+pn*an

    知道了n,我们就知道了n个系数p了,sum也知道

    所以只要枚举1~n的排列,刚哪一个排列符合等式就ok了

    又要字典序顺序,所以我们从小到大的顺序枚举,一有答案了,就跳出来。

     1 #include<cstdio>
     2 #include<cstring>
     3 
     4 using namespace std;
     5 
     6 const int maxn=13;
     7 int c[maxn][maxn];
     8 int a[maxn];
     9 int n,sum;
    10 bool flag;
    11 
    12 void init_c()
    13 {
    14     memset(c,0,sizeof c);
    15     for(int i=1;i<maxn;i++)
    16     {
    17         c[i][1]=1;
    18         for(int j=2;j<=i;j++)
    19             c[i][j]=c[i-1][j-1]+c[i-1][j];
    20     }
    21 }
    22 
    23 void solve()
    24 {
    25     int ret=0;
    26     for(int i=1;i<=n;i++)
    27     {
    28         ret+=c[n][i]*a[i];
    29     }
    30     if(ret==sum)
    31     {
    32         flag=true;
    33         for(int i=1;i<n;i++)
    34             printf("%d ",a[i]);
    35         printf("%d
    ",a[n]);
    36     }
    37     return ;
    38 }
    39 
    40 void next(int cur)
    41 {
    42     if(flag)
    43         return ;
    44     if(cur==n+1)
    45     {
    46         solve();
    47         return ;
    48     }
    49     for(int i=1;i<=n;i++)
    50     {
    51         int ok=1;
    52         for(int j=1;j<cur;j++)
    53         {
    54             if(a[j]==i)
    55                 ok=0;
    56         }
    57         if(ok)
    58         {
    59             a[cur]=i;
    60             next(cur+1);
    61         }
    62     }
    63 
    64 }
    65 
    66 int main()
    67 {
    68     init_c();
    69     while(~scanf("%d%d",&n,&sum))
    70     {
    71         flag=false;
    72         next(1);
    73     }
    74     return 0;
    75 }
    View Code
  • 相关阅读:
    Codeforces Round #246 (Div. 2):B. Football Kit
    iOS8使用TouchID
    HDU 1796 How many integers can you find(容斥原理+二进制/DFS)
    MapReduce的Reduce side Join
    Android入门级编译错误汇总
    当往事已随风
    静态链表的C++实现
    《跨界杂谈》企业商业模式(三):集约
    C
    Android插屏动画效果
  • 原文地址:https://www.cnblogs.com/-maybe/p/4699593.html
Copyright © 2020-2023  润新知