P1118 [USACO06FEB]数字三角形`Backward Digit Su`… 回溯法
有这么一个游戏:
写出一个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行,为字典序最小的那个答案。
当无解的时候,请什么也不输出。(好奇葩啊)
输入输出样例
说明
对于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[];
int yhsj[][];
int main()
{
int n;
int sum;
RII(n,sum);
rep(i,,n)
a[i]=i; yhsj[][]=;
rep(i,,n)
rep(j,,i)
yhsj[i][j]=yhsj[i-][j-]+yhsj[i-][j]; int b[];
do
{
int all=;
int ok=;
rep(i,,n)
{
all+=a[i]*yhsj[n][i];
if(all>sum){ok=;break;}
}
if(ok&&all==sum)
{
rep(i,,n)
{
if(i!=)
printf(" ");
printf("%d",a[i]);
}
break;
} }
while(next_permutation(a+,a++n));
return ;
}
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[];
int yhsj[][];
int main()
{
int n;
int sum;
RII(n,sum);
rep(i,,n)
a[i]=i; yhsj[][]=;
rep(i,,n)
rep(j,,i)
yhsj[i][j]=yhsj[i-][j-]+yhsj[i-][j]; do
{
int all=;
int ok=;
rep(i,,n)
{
all+=a[i]*yhsj[n][i];
if(all>sum){ok=;sort(a+i,a++n,greater<int>()); break;}
}
if(ok&&all==sum)
{
rep(i,,n)
{
if(i!=)
printf(" ");
printf("%d",a[i]);
}
break;
}
}
while(next_permutation(a+,a++n));
return ;
}
其实这题用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 105 int a[];
int yhsj[][];
int vis[];
int sum,n;
int ok=;
int ans[];
void dfs(int now,int all)
{
if(ok)return ;
if(now==n+&&all==sum)
{
ok=;
rep(i,,n)
{
if(i!=)
printf(" ");
printf("%d",ans[i]);
}
return ;
}
rep(i,,n)
{
if(vis[i])continue;
if(all+i*yhsj[n][now]>sum)continue;
vis[i]=;
ans[now]=i;
dfs(now+,all+i*yhsj[n][now]);
vis[i]=;
}
return ;
}
int main()
{
RII(n,sum);
rep(i,,n)
a[i]=i; yhsj[][]=;
rep(i,,n)
rep(j,,i)
yhsj[i][j]=yhsj[i-][j-]+yhsj[i-][j]; dfs(,); return ;
}
P1118 [USACO06FEB]数字三角形`Backward Digit Su`… 回溯法的更多相关文章
- P1118 [USACO06FEB]数字三角形`Backward Digit Su`…
题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 11 to N(1 \le N \ ...
- 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 ...
- 洛谷—— P1118 [USACO06FEB]数字三角形Backward Digit Su…
https://www.luogu.org/problem/show?pid=1118#sub 题目描述 FJ and his cows enjoy playing a mental game. Th ...
- P1118 [USACO06FEB]数字三角形`Backward Digit Su`… (dfs)
https://www.luogu.org/problemnew/show/P1118 看的出来是个dfs 本来打算直接从下到上一顿搜索 但是不会 看了题解才知道系数是个杨辉三角....... 这样就 ...
- 洛谷P1118 [USACO06FEB]数字三角形`Backward Digit Su`…
#include<iostream> using namespace std ; ; int y[N][N]; int n; int a[N]; bool st[N]; int sum; ...
- luoguP1118 [USACO06FEB]数字三角形`Backward Digit Su`… 题解
一上午都在做有关搜索的题目,,, 看到这题之后就直接开始爆搜 结果只有70分, 其余的点硬生生的就是那么WA了. 我的天哪~ 70分代码: #include<iostream> #incl ...
- Luogu P1118 [USACO06FEB]数字三角形 Backward Digit Sums | 搜索、数学
题目链接 思路:设一开始的n个数为a1.a2.a3...an,一步一步合并就可以用a1..an表示出最后剩下来的数,不难发现其中a1..an的系数恰好就是第n层杨辉三角中的数.所以我们可以先处理出第n ...
- 【洛谷P1118】数字三角形
数字三角形 题目链接 4 16 3 1 2 4 3 1 2 4 (3+1) (1+2) (2+4)(3+1+1+2) (1+2+2+4) (3+1+1+1+2+2+2+4)16=1*3+3*1+3*2 ...
- [USACO06FEB]数字三角形
题目描述 FJ and his cows enjoy playing a mental game. They write down the numbers from 1 to N (1 <= N ...
随机推荐
- 42)django-Model _meta API
一:Model _meta API 模型_metaAPI是Django ORM的核心.它使系统的其他部分(如查询,查询,表单和管理员)了解每个模型的功能. API可以通过_meta每个模型类的属性来访 ...
- 18)django-模板的过滤器和tag,自定义simple_tag和filter
模板过滤器是在变量被显示前修改它的值的一个简单方法. 过滤器使用管道字符 . 模板标签(template tag) .标签(tag)定义比较明确,即: 仅通知模板系统完成某些工作的标签. 一:dja ...
- 解决Javascript中$(window).resize()多次执行(转)
https://www.cnblogs.com/shuilangyizu/p/6816756.html 有些时候,我们需要在浏览器窗口发生变化的时候,动态的执行一些操作,比如做自适应页面时的适配.这个 ...
- ORACLE的数据类型的长度合集
-- ORACLE的数据类型常用的数据库字段类型如下:字段类型 中文说明 限制条件 其它说明CHAR 固定长度字符串 最大长度2000 bytesVARCHAR2 可变长度的字符串 最大长度4000 ...
- Confluence 6 配置字符集编码
Confluence 和你的数据库必须配置使用相同的字符集.为了避免字符出现问题,请将所有的字符集设置为使用 UTF-8 编码(或者根据你配置的数据库来制定正确的 UTF-8 编码字符集,例如在 Or ...
- vue的多选框
- linux下安装mysql-5.6.41
1.下载安装包,下载地址:https://dev.mysql.com/downloads/mysql/5.7.html#downloads .选择完版本,然后点击下方 No thanks, just ...
- ShadingJdbc学习
可参考:https://blog.csdn.net/jadebai/article/details/86716082 https://blog.csdn.net/jadebai/article/det ...
- 开始接触python
1.什么是语言? 语言是一个事物与另一个事物交流的介质 python是人与计算机交流的介质 能够被计算机所识别的表达方式即是编程语言 2.什么是编程? 编程就是程序员将想让计算机做的事情用编程语言表达 ...
- go-web项目性能测试,CPU, 内存泄露等
go中提供了pprof包来做代码的性能监控,在两个地方有包: net/http/pprof runtime/pprof 其实net/http/pprof中只是使用runtime/pprof包来进行封装 ...