3187.Backward Digit Sums
Description
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
结题思路 :
题意要求我们找到字典序最小的可行解。
要求1:杨辉三角的形式进行数据逐行的累加;
要点2:根据题意,实际上将杨辉三角进行倒转以后,三角中的每个数就代表题目中这个数被累加的次数;
要求3:暴力求解,利用杨辉三角的法则直接计算每个数最后被累加的次数。
杨辉三角第n层第k个数记为:(PS 我们的第一个是从0开始计数的哟)
Ckn=n!k!(n−k)!=n∗(n–1)…∗(n–k+1)k!
程序步骤:
第一步、首先构建字典序最小的一组解。
第二步、通过累加每个数被累加的和来判断这组解的可行性。
第三步、找到可行数组直接终止循环输出解。
具体程序(AC)如下:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
//这个位置的数被累加的次数
int count(int n, int k)
{
int result = 1;
for(int i = 0; i < k; ++i)
result = result * (n - i) / (i + 1);
return result;
}
int main()
{
int n, result;
cin>>n >>result;
vector<int> listVal(n);
for(int i = 0; i < n; ++i)
listVal[i] = i + 1;
int final;
do{
final = 0;
for(int i = 0; i < n; ++i)
final += listVal[i] * count(n - 1, i);
if(final == result)//找到优解
{
if(n > 0)
cout<<listVal[0];
for(int i = 1; i < n; ++i)
cout<<" "<<listVal[i];
cout<<endl;
break;
}
}while(next_permutation(listVal.begin(), listVal.end()));
return 0;
}