华师一附中OI组
标题: P1118 [USACO06FEB]数字三角形`Backward Digit Su`… [打印本页]
作者: 倚窗倾听风吹雨 时间: 2018-8-20 11:12
标题: P1118 [USACO06FEB]数字三角形`Backward Digit Su`…
https://www.luogu.org/problemnew/show/P1118
有这么一个游戏:
写出一个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:
416
输出样例#1:
31 2 4
说明
对于40%的数据,n≤7 ;
对于 80% 的数据, n≤10;
对于100%的数据, n≤12,sum≤12345。
作者: 倚窗倾听风吹雨 时间: 2018-8-20 11:12
- #include<iostream>
- #include<cmath>
- #include<cstring>
- #include<cstdlib>
- #include<cstdio>
- using namespace std;
- int n,sum,sum0;
- int a[20],b[20],c[20];
- void dfs(int p)
- {
- if (sum0>sum) return;
- if (p==n+1)
- {
- //cout<<sum0<<endl;
- if (sum0==sum)
- {
- for (int j=1;j<=n;j++) cout<<c[j]<<' '; cout<<endl; sum=-1;
- }
- return;
- }
- for (int i=1;i<=n;i++)
- {
- if (b[i]) continue;
- b[i]=1; c[p]=i; sum0+=a[p]*i;
- dfs(p+1);
- b[i]=0; sum0-=a[p]*i;
- }
- }
- int main()
- {
- /// freopen("backward.in","r",stdin);
- /// freopen("backward.out","w",stdout);
- cin>>n>>sum;
- for (int i=1;i<=n;i++)
- {
- a[i]=1; a[1]=1;
- for (int j=2;j<=i-1;j++) a[j]=b[j]+b[j-1];
- for (int j=1;j<=i;j++) b[j]=a[j];
- }
- for (int i=1;i<=n;i++) b[i]=0;
- sum0=0; dfs(1);
- return 0;
- }
复制代码
作者: admin 时间: 2018-8-20 13:41
不是可以用类似杨辉三角那样的公式去求得到吗?
作者: 倚窗倾听风吹雨 时间: 2018-8-21 10:27
主程序里就是先算出了杨辉三角存起来了啊
作者: 倚窗倾听风吹雨 时间: 2018-8-21 10:28
主程序里就是先算出了杨辉三角存起来了啊
欢迎光临 华师一附中OI组 (http://hsyit.cn/) |
Powered by Discuz! X3.2 |