zoukankan      html  css  js  c++  java
  • POJ 3187 Backward Digit Sums

    题意:

    我们把1-n这n个数的某个排列摆成一排,然后相邻两个数的和放到下一行,依此类推,形成一个三角形

    3   1    2   4

       4   3   6

         7   9

          16

    给你n和最终得到的和k,求第一行的系列(字典序最小)

    我们可以发现每个数字的计算次数是一个杨辉三角

                 1   1

              1    2    1

           1    3     3    1

       1     4     6      4     1

                  ......

    所以我们只要枚举1-n的全排列,计算sum{ans[i]*c(i-1,n-1)}是否为K就行了

    当然从顶层一步一步算到最低也是一样的

    10!为380W,而且因为左右对称,规模能减一半

    枚举全排序能用STL中的next_permutation能很方便的求出

    如果不知道这个函数,就写个DFS

     //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<cmath>
    #include<climits>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    #define pb(a) push_back(a)
    #define INF 0x1f1f1f1f
    #define lson idx<<1,l,mid
    #define rson idx<<1|1,mid+1,r
    #define PI  3.1415926535898
    void debug()
    {
    #ifdef ONLINE_JUDGE
    #else
        freopen("d:\in.txt","r",stdin);
       // freopen("d:\out1.txt","w",stdout);
    #endif
    }
    char getch()
    {
        char ch;
        while((ch=getchar())!=EOF)
        {
            if(ch!=' '&&ch!='
    ')return ch;
        }
        return EOF;
    }
    
    int cc(int m,int n)
    
    {
        int k=1;
        for(int i=0;i<n;i++)
            k*=(m-i);
        for(int i=1;i<=n;i++)
            k/=i;
        return k;
    
    }
    int c[11][11];
    int n,k;
    int ans[11];
    int main()
    {
        for(int i=1;i<=10;i++)    //预处理出全部C(n,i),只是在追求速度,可以不必
            for(int j=0;j<=i;j++)
                c[i][j]=cc(i,j);
        while(scanf("%d%d",&n,&k)!=EOF)
        {
            for(int i=1;i<=n;i++)ans[i]=i;
            do
            {
                int sum=0;
                for(int i=1;i<=n;i++)
                    sum+=ans[i]*c[n-1][i-1];
                if(sum==k)break;
            }while(next_permutation(ans+1,ans+1+n));
            for(int i=1;i<=n;i++)
                printf("%d%c",ans[i],i==n?'
    ':' ');
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Java 代理模式
    ReentrantLock 详解
    Java线程池详解
    ConcurrentHashMap 解读
    CountDownLatch/CyclicBarrie用法记录
    微信接入笔记记录
    iOS设计模式
    iOS设计模式
    iOS设计模式
    iOS设计模式
  • 原文地址:https://www.cnblogs.com/BMan/p/3238267.html
Copyright © 2011-2022 走看看