• [luogu p1118] [USACO06FEB]数字三角形


    题面

    题目描述

    FJ and his cows enjoy playing a mental game. They write down the numbers from (1) to$ N(1 le N le 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.

    有这么一个游戏: 写出一个(1)(N)的排列(a_i),然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少(1),直到只剩下一个数字位置。下面是一个例子:

    (3,1,2,4)

    (4,3,6)

    (7,9)

    (16) 最后得到(16)这样一个数字。 现在想要倒着玩这样一个游戏,如果知道(N),知道最后得到的数字的大小(sum),请你求出最初序列(a_i),为(1)(N)的一个排列。若答案有多种可能,则输出字典序最小的那一个。

    管理员注:本题描述有误,这里字典序指的是(1,2,3,4,5,6,7,8,9,10,11,12) 而不是(1,10,11,12,2,3,4,5,6,7,8,9)

    输入输出格式

    输入格式

    两个正整数(n,sum)

    输出格式

    输出包括(1)行,为字典序最小的那个答案。 当无解的时候,请什么也不输出。(好奇葩啊)

    输入输出样例

    输入样例 #1

    4 16
    

    输出样例 #1

    3 1 2 4
    

    说明

    对于(40\%)的数据,(n≤7)
    对于(80\%)的数据,(n≤10)
    对于(100\%)的数据,(n≤12,sum≤12345)

    分析

    这道题明显是搜索,但无脑枚举next_permutation时间复杂度爆炸,所以我们不妨推推式子找规律。
    如果三角形有(n)层,第一行的数分别为(a_1,a_2,ldots,a_n),我们能推出(sum)值吗?
    如果(n = 1),那么答案显然为(a_1)
    如果(n = 2),答案就是上一层两者之和,自然为(a_1+a_2)
    如果(n = 3),画出三角:

    [a_1qquad quad a_2qquad quad a_3 \ a_1+a_2 quad a_2+a_3 \ a_1+2a_2+a_3 ]

    答案为(a_1+2a_2+a_3)
    如果(n = 4)

    [a_1qquad qquad a_2qquad qquad a_3 qquadqquad a_4\ a_1+a_2 qquad a_2+a_3 qquad a_3+a_4\ a_1+2a_2+a_3 quad a_2+2a_3+a_4\ a_1+3a_2+3a_3+a_4 ]

    答案为(a_1+3a_2+3a_3+a_4)
    如果(n = 5)

    [a_1qquad qquad quad a_2qquad qquad quad a_3 qquadqquad quad a_4 qquadqquad a_5\ a_1+a_2 qquad quad a_2+a_3 qquad quad a_3+a_4 qquad quad a_4+a_5\ a_1+2a_2+a_3 quad a_2+2a_3+a_4 quad a_3+2a_4+a_5\ a_1+3a_2+3a_3+a_4 quad a_2+3a_3+3a_4+a_5\ a_1+4a_2+6a_3+4a_4+a_5 ]

    答案为(a_1+4a_2+6a_3+4a_4+a_5)
    列个表:

    (n) (sum)
    (1) (a_1)
    (2) (a_1+a_2)
    (3) (a_1+2a_2+a_3)
    (4) (a_1+3a_2+3a_3+a_4)
    (5) (a_1+4a_2+6a_3+4a_4+a_5)
    (6) (a_1+5a_2+10a_3+10a_4+5a_5+a_6)
    (ldots) (dots)

    如果我们抛掉字母不看,只剩下系数,会得到什么结果?

    (n) ( ext{coefficient})
    (1) (1)
    (2) (1,1)
    (3) (1,2,1)
    (4) (1,3,3,1)
    (5) (1,4,6,4,1)
    (6) (1,5,10,10,5,1)
    (ldots) (dots)

    聪明的你一定看出来了,这就是杨辉三角。
    而题目呢恰好是已知(sum),求原式子,而(n)(sum)和原数组就被杨辉三角紧紧绑在一起。我们只需要通过搜索枚举出当前数字乘上杨辉三角的对应数字,然后相加看看是否等于(sum),如果等于输出,结束。
    杨辉三角这里我们可以用一个公式预处理:

    [C^0_n = 1\ C^k_n = frac{n+1-k}{k} C^{k-1}_n ]

    代码

    #include <iostream>
    #include <cstdio>
    
    const int maxn = 25;
    int n,sum;
    bool vis[maxn];
    int ans[maxn];
    int c[maxn];
    
    bool dfs(int nownum, int nowsum, int step) {
        if (nowsum > sum) return false;//可行性剪枝
        if (step == n) {
            if(nowsum == sum) {
                ans[n] = nownum;
                return true;
            }
            return false;//同样是可行性剪枝,但评测的时候我没写这句也AC了umm
        }
    
        vis[nownum] = true;
        for (int j = 1; j <= n; j++) {
            if (vis[j]) continue;
            if(dfs(j,nowsum+c[step]*j,step+1)) {
                ans[step] = nownum;
                return true;
            }
        }
    
        vis[nownum] = false;//回溯
        return false;
    }
    
    void pastri() {
        c[0] = c[n-1] = 1;
        if (n == 1) return ; 
        for (int i = 1; i * 2 < n; i++)
            c[i] = c[n-i-1] = (n-i) * c[i-1] / i;
    }//用组合数预处理杨辉三角。
    
    int main() {
        scanf("%d%d",&n,&sum);
        pastri();
    
        if (dfs(0,0,0)) 
            for (int i = 1; i <= n; i++)
                printf("%d ",ans[i]);
    
        puts("");
        return 0;
    }
    

    评测记录

    AC 100:R30917956

    over.

  • 相关阅读:
    Socket编程
    jdbc03 使用servlet实现
    el和jstl
    java03变量和基本数据类型
    java02
    ssh整合
    U1总结
    多线程
    spring07 JDBC
    cocos2dx中的三种基本的数据类型
  • 原文地址:https://www.cnblogs.com/crab-in-the-northeast/p/luogu-p1118.html
Copyright © 2020-2023  润新知