5.1 merge algorithm design and analysis fruit

★ Title Description

GYY fruit heap in front of N, respectively 1,2,3 ,. . . . , N a fruit, a fruit which begins N pile arranged in a certain order.

GYY has a unique magic, he would turn round operation of the fruit of the first i + 1 is added to the heap copy of the i-heap, and finally the last discard pile.

After N rounds operation, on the left a pile of fruit (nonsense).

However, when GYY finished busy all this, he found that he forgot N fruit heap is how I initially placed, and

You are given the number of operations and the number of final round pile of fruit, to find the initial arrangement to meet the conditions of a

If there are multiple solutions that a lexicographically smallest output.

★ input format

Only the input line, comprising two positive integers N and the Sum, showing a stack of fruit began N

After the operation of the pile of fruit remaining N wheel has a Sum.

★ output format

Output comprising N integers, separated by a space between two adjacent integers, is output if no solution "GG",

If the set of solutions that multiple solutions lexicographically smallest output.

Note that the end of the line an extra space may lead to wrong answer.

★ sample input

4 16

★ Sample Output

3 1 2 4

★ Tips

2. 1. 4. 3
. 4. 3. 6
. 7. 9
16
to 60% of the data, N <= 7;
100% of the data, N <= 12, Sum < = 20000.

★ reference code

/*
每堆果子合并次数的规律符合杨辉三角
下面是一个杨辉三角
      1
    1   1
  1   2   1
1   3   3   1 
用杨辉三角作为系数, 乘上每堆果子的数量应该为sum
1*3 + 3*1 + 3*2 + 1*4 = 16 


数据量好像不大,尝试一下回溯穷举果子数量的排列

所以接下来的问题就是按照字典序的顺序生成果子数量方案 
生成全排列方案可以使用next_permutation 
*/
#include<bits/stdc++.h>
using namespace std;

int N,Sum;
int yhs[13]; 
int res[13]; 
int ok=0;

int IsCorr(){
    int ans=0;
    for(int i=1; i<=N; ++i) ans+=yhs[i]*res[i];
    return Sum==ans;
} 


int main(){
    scanf("%d%d",&N, &Sum);
    
    //构造杨辉三角
    memset(yhs, 0, sizeof(yhs)), yhs[1]=1;
    for(int k=2; k<=N; ++k){
        for(int i=k; i>0; --i){
            yhs[i]=yhs[i]+yhs[i-1];
        }
    }

    //穷举每堆果子可能的个数,按字典序穷举 
    for(int i=1; i<=N; ++i) res[i]=i;
    do {
        if(IsCorr()){
            ok=1;
            break;
        }
    } while(next_permutation(res+1, res+N+1));
    
    //结果输出
    if(ok){
        for(int i=1; i<=N; ++i) printf("%d ",res[i]);
        printf("\n");
    } 
    else printf("GG\n");
    return 0;
} 

Guess you like

Origin www.cnblogs.com/yejifeng/p/12080000.html