zoukankan      html  css  js  c++  java
  • POJ 3187 Backward Digit Sums (dfs,杨辉三角形性质)

    FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N <= 10) in a certain order and then sum adjacent numbers to produce a new list with one fewer number. They repeat this until only a single number is left. For example, one instance of the game (when N=4) might go like this:

        3   1   2   4
    
    4 3 6
    7 9
    16
    Behind FJ's back, the cows have started playing a more difficult game, in which they try to determine the starting sequence from only the final total and the number N. Unfortunately, the game is a bit above FJ's mental arithmetic capabilities.

    Write a program to help FJ play the game and keep up with the cows.

    Input

    Line 1: Two space-separated integers: N and the final sum.

    Output

    Line 1: An ordering of the integers 1..N that leads to the given sum. If there are multiple solutions, choose the one that is lexicographically least, i.e., that puts smaller numbers first.

    Sample Input

    4 16

    Sample Output

    3 1 2 4

    Hint

    Explanation of the sample:

    There are other possible sequences, such as 3 2 1 4, but 3 1 2 4 is the lexicographically smallest.
     
     
    这个题竟然是深搜,看得题目中说用全排列字典序输出有点吓人...
    我们先来看一下杨辉三角形的性质。第n行第m个数的值是C上m 下n-1 (组合数打不出来啊...),由于杨辉三角形的形成过程的逆过程。我们可以知道sum的最终和
    sum=0 C n-1*ans[0]+1 C n-1*ans[1]+2 C n-1*ans[2]+3 C n-1*ans[3]+4 C n-1*ans[4]+......
    好好理解这个逆过程因为杨辉三角形一开始都是用1加起来的,所以我们从底下往上加的时候,每个最底层的数在求和时算了多少次?那个次数就是底层数字对应杨辉三角形的值。
    剩下的交给深搜了。
     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 int a[15][15],n,sum,vis[15],ans[15];
     5 bool f;
     6 void setnum ()//生成杨辉三角形
     7 {
     8     for (int i=0;i<n;++i)
     9     {
    10         a[i][0]=1;
    11         a[i][i]=1;
    12     }
    13     for (int i=2;i<n;++i)
    14         for (int j=1;j<i;++j)
    15         a[i][j]=a[i-1][j-1]+a[i-1][j];
    16 }
    17 void printAns ()
    18 {
    19     for (int i=0;i<n;++i)
    20     {
    21         printf("%d",ans[i]);
    22         if (i!=n-1)
    23         printf(" ");
    24     }
    25     printf("
    ");
    26 }
    27 void dfs (int nowsum,int step)//这样的搜索是刚好字典序的
    28 {
    29     if (step==n)
    30     {
    31         if (nowsum==sum)
    32         {
    33             f=true;
    34             printAns();
    35         }
    36         return ;
    37     }
    38     if (f||nowsum>sum)
    39     return ;
    40     for (int i=1;i<=n;++i)
    41     {
    42         if (vis[i])
    43         continue;
    44         vis[i]=1;
    45         ans[step]=i;
    46         dfs(nowsum+i*a[n-1][step],step+1);
    47         vis[i]=0;//每次搜完以后要清空状态
    48     }
    49 }
    50 int main()
    51 {
    52     scanf("%d%d",&n,&sum);
    53     setnum();
    54     f=false;
    55     memset(vis,0,sizeof vis);
    56     memset(ans,0,sizeof ans);
    57     dfs(0,0);
    58     return 0;
    59 }
  • 相关阅读:
    阿里云服务器mysql连接不了2003 -can't connect to mysql server on 'ip' (10038)
    androidstudio代码混淆
    apk反编译
    android bottomnavicationbar底部图标vector设计
    Java++:不要随意使用 Cookie 会引火烧身的
    Java++:用户认证-基于 jwt 和 session 的区别和优缺点
    Spring++:AOP 拦截 Service | Controller 日志
    Spring++:整合 Retry 实现重试机制
    (xxl_job | quartz):XXL_JOB 对比 Quartz 一决高下!
    Spring++:定时任务 Cron表达式详解
  • 原文地址:https://www.cnblogs.com/agenthtb/p/5889972.html
Copyright © 2011-2022 走看看