• 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 }
  • 相关阅读:
    log4net 简单使用教程(配置)
    C#WinForm 国际化的简单实现,多语言实现
    EF Power Tool 参数错误 HRESULT:0x80070057 (E_INVALIDARG)) 解决办法
    如何用委托与事件实现winfrom窗体之间值传递
    VS2010自带的Dotfuscator 5注册
    WinForm 实现主程序(exe)与其关联类库(*.dll)分开存放
    POJ_3211 Washing Clothes (01背包)
    POJ_3624 Charm Bracelet ( 01背包 )
    集训队内部测试赛(2012.01.02)
    HDU_1011 Starship Troopers && HDU_1561 The more, The Better (树型dp)
  • 原文地址:https://www.cnblogs.com/agenthtb/p/5889972.html
Copyright © 2020-2023  润新知