有这么一个游戏:

写出一个11至NN的排列a_iai​,然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少11,直到只剩下一个数字位置。下面是一个例子:

3,1,2,43,1,2,4

4,3,64,3,6

7,97,9

1616

最后得到1616这样一个数字。

现在想要倒着玩这样一个游戏,如果知道NN,知道最后得到的数字的大小sumsum,请你求出最初序列a_iai​,为11至NN的一个排列。若答案有多种可能,则输出字典序最小的那一个。

[color=red]管理员注:本题描述有误,这里字典序指的是1,2,3,4,5,6,7,8,9,10,11,121,2,3,4,5,6,7,8,9,10,11,12

而不是1,10,11,12,2,3,4,5,6,7,8,91,10,11,12,2,3,4,5,6,7,8,9[/color]

输入输出格式

输入格式:

两个正整数n,sumn,sum。

输出格式:

输出包括11行,为字典序最小的那个答案。

当无解的时候,请什么也不输出。(好奇葩啊)

输入输出样例

输入样例#1: 复制

4 16

输出样例#1: 复制

3 1 2 4

说明

对于40\%40%的数据,n≤7n≤7;

对于80\%80%的数据,n≤10n≤10;

对于100\%100%的数据,n≤12,sum≤12345n≤12,sum≤12345。

一开始用模拟法  超时3个点

然后观察发现  累合的乘数为杨辉三角   用杨辉三角优化 超时2个点

#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//
#define N 105
int a[16];
int yhsj[15][15];
int main()
{int n;int sum;RII(n,sum);rep(i,1,n)a[i]=i;yhsj[1][1]=1;rep(i,2,n)rep(j,1,i)yhsj[i][j]=yhsj[i-1][j-1]+yhsj[i-1][j];int b[16];do{int all=0;int ok=1;rep(i,1,n){all+=a[i]*yhsj[n][i];if(all>sum){ok=0;break;}}if(ok&&all==sum){rep(i,1,n){if(i!=1)printf(" ");printf("%d",a[i]);}break;}}while(next_permutation(a+1,a+1+n));return 0;
}

2 TLE

参考了大佬的做法

其实只要加一个关键剪枝即可

如果加到i处过不去了   把i及其后面的数降序排列好  下一个next就是 累合杨辉三角的最小值了  !!!!(因为杨辉三角中间大  两边小)

#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//
#define N 105
int a[16];
int yhsj[15][15];
int main()
{int n;int sum;RII(n,sum);rep(i,1,n)a[i]=i;yhsj[1][1]=1;rep(i,2,n)rep(j,1,i)yhsj[i][j]=yhsj[i-1][j-1]+yhsj[i-1][j];do{int all=0;int ok=1;rep(i,1,n){all+=a[i]*yhsj[n][i];if(all>sum){ok=0;sort(a+i,a+1+n,greater<int>());   break;}}if(ok&&all==sum){rep(i,1,n){if(i!=1)printf(" ");printf("%d",a[i]);}break;}}while(next_permutation(a+1,a+1+n));return 0;
}

View Code

其实这题用dfs回溯法更见简单高效   上面那个剪枝其实很难想到

不要过度依赖STL  有时候效率非常低下

#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//
#define N 105int a[16];
int yhsj[15][15];
int vis[16];
int sum,n;
int ok=0;
int ans[16];
void dfs(int now,int all)
{if(ok)return ;if(now==n+1&&all==sum){ok=1;rep(i,1,n){if(i!=1)printf(" ");printf("%d",ans[i]);}return ;}rep(i,1,n){if(vis[i])continue;if(all+i*yhsj[n][now]>sum)continue;vis[i]=1;ans[now]=i;dfs(now+1,all+i*yhsj[n][now]);vis[i]=0;}return ;
}
int main()
{RII(n,sum);rep(i,1,n)a[i]=i;yhsj[1][1]=1;rep(i,2,n)rep(j,1,i)yhsj[i][j]=yhsj[i-1][j-1]+yhsj[i-1][j];dfs(1,0);return 0;
}

View Code

转载于:https://www.cnblogs.com/bxd123/p/10664413.html

P1118 [USACO06FEB]数字三角形`Backward Digit Su`… 回溯法相关推荐

  1. P1118 [USACO06FEB]数字三角形Backward Digit Su…

    P1118 [USACO06FEB]数字三角形Backward Digit Su- 题目描述 FJ and his cows enjoy playing a mental game. They wri ...

  2. 洛谷—— P1118 [USACO06FEB]数字三角形Backward Digit Su…

    https://www.luogu.org/problem/show?pid=1118#sub 题目描述 FJ and his cows enjoy playing a mental game. Th ...

  3. 洛谷 P1118 [USACO06FEB]数字三角形Backward Digit Su…

    题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N ...

  4. P1118 [USACO06FEB]数字三角形`Backward Digit Su`…

    题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 11 toN(1 \le N \l ...

  5. 洛谷P1118 [USACO06FEB]数字三角形Backward Digit Su…

    题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N ...

  6. 洛谷P1118 [USACO06FEB]数字三角形 Backward Digit Su(dfs剪枝)

    题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 11 toN(1 \le N \l ...

  7. P1118 [USACO06FEB]数字三角形`Backward Digit Su`…(C++_DFS)

    题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 11 toN(1 \le N \l ...

  8. 杨辉三角 [USACO06FEB]数字三角形Backward Digit Su…

    杨辉三角 简单的说一下就是两个未知数和的幂次方运算后的系数问题,比如(x+y)的平方=x的平方+2xy+y的平方,这样系数就是1,2,1这就是杨辉三角的其中一行,立方,四次方,运算的结果看看各项的系数 ...

  9. [USACO06FEB]数字三角形Backward Digit Su…

    题目描述 3 1 2 44 3 67 916 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少 ...

最新文章

  1. hung-yi lee_p18_图神经网络(cont.)
  2. ylinux系统找到软件_电脑用了段时间发现多处一些软件该怎么办?
  3. 我看UNIX与Windows的本质区别
  4. CMDB经验分享之 – 剖析CMDB的设计过程
  5. BoostrapTable的refresh和refreshOptions区别
  6. WinForm 快捷键设置
  7. LAMP兄弟连2011年上半年开班计划
  8. 1~3年产品经理经典面试题
  9. 收藏到一个好的java时间格式大全(类)
  10. 计算机内存槽清理,内存插槽修复方法
  11. Redis 哨兵安装-Centos
  12. docker镜像的获取删除和查看镜像信息历史记录清理残余镜像
  13. mysql同步大师_Mysql 同步大师(MySQLSync)
  14. apache commons fileupload 团队
  15. java代码实现短信接受验证码
  16. Websocket(二)-客户端与服务器通信
  17. linux--积累--分析清理服务器大文件--分析清理磁盘空间
  18. 【C++实训】基于MVC模型开发的高校教务管理系统【附完整报告+示例程序+日记+源码】
  19. 20款精美APP和Web设计模板素材(附演示链接)
  20. 哎,开发又被骗了……

热门文章

  1. Word中邮件功能的使用
  2. 友善之臂NanoPC T4资料
  3. 五轴数控转台_五轴机床有很多种类型,你都知道吗?
  4. 毫安时,毫瓦时的含义
  5. python实现流媒体,python +OpenCV实现rtmp视频流媒体的播放
  6. 禁止暴风影音的自动升级的方法
  7. Word简历如何插入个人头像?
  8. 依赖反转(倒置)原则(Dependency inversion principle,DIP)
  9. 关于flash remotObject
  10. Java简单项目:公司人员管理系统