洛谷P1118[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 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.

解题思路:
现在已知 N t h e f i n a l   t o t a l ,要找出原来的序列,如果直接搜索会花费 N ! 时间复杂度。考虑剪枝的话也会 T L E ,但是通过观察上面这段序列,如果设第一行4个数分别为 a , b , c , d ,则最后的结果为 a + 3 b + 3 c + d ,考虑到杨辉三角的形式:

            1
        1      1
    1       2      1
1       3       3     1
......

可以发现这段序列最后的值等于杨辉三角第4行的值与序列乘积的加权。然后再利用 d f s 就可以解决了。

#include <iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,sum,total=0,flag=0;
int a[100];
int h[100],vis[100],loc[100],yh[100][100];
void dfs(int step,int num){
    if(num>sum||flag)
        return;
    if(step==n+1){//结束条件 
        if(num==sum){
            for(int i=1;i<=n;i++){
                cout<<loc[i]<<" ";
            }
            cout<<endl;
            flag=1;
        }
        return;
    }
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            vis[i]=1;
            a[step]=i,loc[step]=i;
            dfs(step+1,num+i*yh[n][step]);//杨辉三角加权
            vis[i]=0;
        }
    }
} 
int main(int argc, char** argv) {

    cin>>n>>sum;
    yh[1][1]=1;
    for(int i=2;i<=n;i++){//构造杨辉三角
        for(int j=1;j<=i;j++){
            yh[i][j]=yh[i-1][j-1]+yh[i-1][j];
        }
    }
    dfs(1,0);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhuixun_/article/details/82696818