[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_1\qquad \quad a_2\qquad \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_1\qquad \qquad a_2\qquad \qquad a_3 \qquad\qquad 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_1\qquad \qquad \quad a_2\qquad \qquad \quad a_3 \qquad\qquad \quad a_4 \qquad\qquad 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\) \(\text{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.

原文地址:https://www.cnblogs.com/crab-in-the-northeast/p/luogu-p1118.html

时间: 2024-08-12 08:30:53

[luogu p1118] [USACO06FEB]数字三角形的相关文章

洛谷P1118 [USACO06FEB]数字三角形 搜索

洛谷P1118 [USACO06FEB]数字三角形Backward Digit Su-     搜索 这题我们发现每一个位置的加权就是 杨辉三角 yh[ n ][ i ] 然后我们就可以求 n! 暴力 ,但是会 TLE 额 好像是会T 因为12! 已经 4亿了然后我们加一个强力剪枝 如果当前求出来的 s 已经大于 sum了,因为没有负的加权,也就是说这一路是没有用了的,在继续搜下去也不能更新答案了,那么就直接退出 . 1 #include <cstdio> 2 #include <cma

P1118 [USACO06FEB]数字三角形Backward Digit Su…

P1118 [USACO06FEB]数字三角形Backward Digit Su… 题目描述 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 rep

做题记录: P1118 [USACO06FEB]数字三角形Backward Digit Su…

P1118 [USACO06FEB]数字三角形Backward Digit Su- /*思路:设一开始的n个数为a1.a2.a3...an, 一步一步合并就可以用a1..an表示出最后剩下来 的数,不难发现其中a1..an的系数恰好就是第n层 杨辉三角中的数.所以我们可以先处理出第n层杨 辉三角中的数,然后根据这一层中的数搜索即可.*/ #include<iostream> #include<cstdio> #include<fstream> #include<a

P1118 [USACO06FEB]数字三角形`Backward Digit Su`…

题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 11 to N(1 \le N \le 10)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 num

P1118 [USACO06FEB]数字三角形`Backward Digit Su`… 回溯法

有这么一个游戏: 写出一个11至NN的排列a_iai?,然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少11,直到只剩下一个数字位置.下面是一个例子: 3,1,2,43,1,2,4 4,3,64,3,6 7,97,9 1616 最后得到1616这样一个数字. 现在想要倒着玩这样一个游戏,如果知道NN,知道最后得到的数字的大小sumsum,请你求出最初序列a_iai?,为11至NN的一个排列.若答案有多种可能,则输出字典序最小的那一个. [

[USACO06FEB]数字三角形

题目描述 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 lef

洛谷P1118 数字三角形游戏

洛谷1118 数字三角形游戏 题目描述 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置.下面是一个例子:     3   1   2   4       4   3   6         7   9          16 最后得到16这样一个数字. 现在想要倒着玩这样一个游戏,如果知道N,知道最后得到的数字的大小sum,请你求出最初序列a[i],为1-N的一个

数字三角形

数字三角形必须经过某一个点,使之走的路程和最大 输入格式: 第1行n,表示n行 (n<=25), 第2到n+1行为每个的权值,第n+2行为两个数x,y表示必须经过的点 输出格式: 输出最大值 样例1 输入: 2 1 1 1 1 1 输出: 2 //11 月 23 日 2015 #include <stdio.h> int num[26][26];//存储数字三角形的权值 int route[26][2];//记录临时最优路径 int n; int s1,s2;//以特殊点分为上半段和下半

蓝桥杯 算法训练 ALGO-124 数字三角形

算法训练 数字三角形 时间限制:1.0s   内存限制:256.0MB 问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜线向下或右斜线向下走: ●1<三角形行数≤100: ●三角形中的数字为整数0,1,-99: . (图3.1-1) 输入格式 文件中首先读到的是三角形的行数. 接下来描述整个三角形 输出格式 最大总和(整数) 样例输入 573 88 1 02 7 4 44 5 2 6 5 样例输出 3