• 洛谷P1118 数字三角形游戏


    洛谷1118 数字三角形游戏

    题目描述

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

    输入输出格式

    输入格式:

    两个正整数n,sum。

    输出格式:

    输出包括1行,为字典序最小的那个答案。
    当无解的时候,请什么也不输出。(好奇葩啊)

    输入输出样例

    输入样例#1:

    4 16

    输出样例#1:

    3 1 2 4

    说明

    对于40%的数据,n≤7;
    对于80%的数据,n≤10;
    对于100%的数据,n≤12,sum≤12345。

    【思路】

      Dfs+杨辉三角。

      以题目数据为例:16=7+9=4+3+3+6=3+1+1+2+1+2+2+4=1*3 + 3*1 + 3*2 + 1*4

      所以可以推出公式sum=∑ Yni*Ai 

      状态包括深度与和,知道了公式可以剪去 和 超过sum的搜索。

    【代码】

     1 #include<iostream>
     2 #include<cstdlib>
     3 using namespace std;
     4 
     5 const int maxn = 14;
     6 
     7 int n,M;
     8 int A[maxn],vis[maxn];
     9 int yn[maxn];
    10 
    11 void get_yn() {
    12     for(int i=0;i<n;i++){
    13        yn[i]=1;
    14        for(int j=i/2;j>0;j--) yn[j]=yn[i-j]=yn[j]+yn[j-1];
    15     }
    16 }
    17 void dfs(int d,int sum) {
    18     if(d==n && sum==M) {
    19         for(int i=0;i<n;i++) cout<<A[i]<<" ";
    20         exit(0);
    21     }
    22     if(sum>M) return ;
    23     for(int i=1;i<=n;i++) if(!vis[i]) {
    24         vis[i]=1;
    25         A[d]=i;
    26         dfs(d+1,sum+yn[d]*i);
    27         vis[i]=0;
    28     }
    29 }
    30 
    31 int main() {
    32     ios::sync_with_stdio(false);
    33     cin>>n>>M;
    34     get_yn();
    35     dfs(0,0);
    36     return 0;
    37 }
  • 相关阅读:
    关于Debian中virtualbox的问题
    aptget和aptitude的区别
    Archlinux安装笔记
    数组全排列的递归方法实现
    Debian卸载iceweasel
    一起学WP7 XNA游戏开发(八. 让3d model动起来)
    一起学windows phone7开发(二十五.Toolkit 增补)
    专业windows phone7开发网站上线
    《一起学Windows phone7开发》系列视频课程
    一起学WindowsPhone7开发(二十六. Advertising)
  • 原文地址:https://www.cnblogs.com/lidaxin/p/4860572.html
Copyright © 2020-2023  润新知