洛谷 - P1118 - 数字三角形 - next_permutation
https://www.luogu.org/problemnew/show/P1118
next_permutation的第二个参数是最后一个元素的下一个元素,sort也是一样!有毒!这么低级的错误。而且应该是用do_while因为原始排列也要考虑!
使用sort跳过一些permutation的原理来源于:
1.假设解存在,那么对称位置的两个元素交换也是一种解
2.我们要求第一种解,必定是左边元素小于右边对应元素的
3.当某个排列导致当前大于sum,怎么证明发现该元素之后的任意排列都是大于sum的呢?
4.假如发现该元素的位置在中间的右侧,那么把更大的元素前移只会让答案变大
5.假如发现该元素的位置在中间的左侧,若这其中有解,必定在之前已经搜索过对应位置的了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
/*
int N,sum; int cntn[13]; int solve(vector<int> &cur,vector<int> &next,int nf){
next.clear();
next.push_back(nf); int pre=nf;
int sz=cur.size();
for(int i=0;i<sz;i++){
int tmp=cur[i]-pre;
if(tmp<=0)
return 0;
next.push_back(tmp);
pre=tmp;
}
return 1;
} void dfs(int n,vector<int> cur){
if(n==N){
//wrong, maybe N+1
int sz=cur.size();
memset(cntn,0,sizeof(cntn)); for(int i=0;i<sz;i++){
if(cur[i]>n||cntn[cur[i]])
return;
else{
cntn[cur[i]]++;
}
} for(int i=0;i<sz;i++){
printf("%d%c",cur[i]," \n"[i==sz-1]);
}
exit(0);
}
else{
vector<int> next;
for(int nextfirst=1;nextfirst<=cur[0]-1;nextfirst++){
int suc=solve(cur,next,nextfirst);
if(suc){
dfs(n+1,next);
}
else{
;
}
}
}
} int main(){
scanf("%d%d",&N,&sum);
vector<int> v;
v.push_back(sum);
dfs(1,v);
} */
int N,sum; int ans[][];
int pas[][]; inline int findsum(){
/*for(int i=2;i<=N;i++){
for(int j=1;j<=N+1-i;j++){
ans[i][j]=ans[i-1][j]+ans[i-1][j+1];
if(ans[i][j]>sum)
return -1;
}
}*/
int tmp=;
for(int i=;i<=N;i++){
//printf("%d ",pas[N][i]);
tmp+=pas[N][i]*ans[][i];
if(tmp>sum){
sort(&ans[][i],&ans[][N]+,greater<int>());
//因为nextpermutation绝对会把大的数字前移,
//根据对称性我们会优先得到小的解,也就是这个不会过半
//所以下一次nextpermutation绝对是会变大的
return -;
}
}
//printf("\n");
//cout<<"tmp="<<tmp<<endl;
return tmp;
} int main(){
scanf("%d%d",&N,&sum); /*if(N<=2){
if(N==1){
if(sum==1){
printf("1\n");
}
}
else{
if(sum==3){
printf("1 2\n");
}
}
return 0;
}*/ for(int i=;i<=N;i++){
ans[][i]=i;
} pas[][]=;
//printf("1\n");
for(int i=;i<=N;i++){
pas[i][]=pas[i][i]=;
for(int j=;j<=i-;j++)
pas[i][j]=pas[i-][j]+pas[i-][j-];
/*for(int j=1;j<=i;j++){
printf("%d ",pas[i][j]);
}
printf("\n");*/
} /*for(int i=1;i<=N;i++){
printf("%d ",pas[N][i]);
}
printf("\n");*/ do{
if(sum==findsum()){
for(int i=;i<N;i++){
printf("%d%c",ans[][i+]," \n"[i==N-]);
}
break;
}
else{
/*for(int i=0;i<N;i++){
printf("%d%c",ans[1][i+1]," \n"[i==N-1]);
}*/
}
}while(next_permutation(&ans[][],&ans[][N]+));
}
洛谷 - P1118 - 数字三角形 - next_permutation的更多相关文章
- 洛谷P1118 数字三角形游戏
洛谷1118 数字三角形游戏 题目描述 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直 ...
- 洛谷P1118 数字三角形【dfs】【STL】
题目链接:https://www.luogu.org/problemnew/show/P1118 题意: 1~n的一个排列,相邻的两项加起来得到下一行. 现在给定最后一行的数字,问最初的1~n的排列是 ...
- 洛谷 P1118 数字三角形游戏 Label:dfs
题目描述 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置.下面是一 ...
- 洛谷P1118数字三角形题解
题目 这个题我们乍一看会有些熟悉.觉得是可以用DP来做的那个题.但是打眼一看,就会发现不对了.因为那个题是顺推而这个题则是逆推. 这样的话可怎么办呢. 我们可以在草稿纸上推一下,我们随便写个数n. 再 ...
- 洛谷P1216 数字三角形【dp】
题目:https://www.luogu.org/problemnew/show/P1216 题意: 给定一个三角形.从顶走到底,问路径上的数字之和最大是多少. 走的时候可以往左下(实际上纵坐标不变) ...
- 洛谷P1216数字三角形题解
题目 这道题是一个典型的DP,可以用倒推,顺推的方法,来解这道题.当然用不同的方法他的循环次序是不一样的,所以我们一定要深刻地理解题目的大意,再采用状态转移方程与边界每次求出最优解,并记录循环一遍后就 ...
- 洛谷P1553 数字翻转(升级版)
题目链接 https://www.luogu.org/problemnew/show/P1553 题目描述 给定一个数,请将该数各个位上数字反转得到一个新数. 这次与NOIp2011普及组第一题不同的 ...
- 【洛谷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 ...
- 洛谷 P5660 数字游戏 & [NOIP2019普及组]
传送门 洛谷改域名了QAQ 解题思路 没什么好说的,一道红题,本不想发这篇博客 ,但还是尊重一下CCF吧QAQ,怎么说也是第一年CSP呢! 用getchar一个个读入.判断.累加,最后输出即可. 不过 ...
随机推荐
- Oracle创建索引的原则(转)
Oracle 建立索引及SQL优化 数据库索引: 索引有单列索引复合索引之说 如何某表的某个字段有主键约束和唯一性约束,则Oracle 则会自动在相应的约束列上建议唯一索引.数据库索引主要进行提高访问 ...
- centos下的hadoop集群实现ssh的无密码登陆
CentOS 下SSH无密码登录的配置 最近学习Hadoop.它要求各节点之间通过SSH无密码登录,配置SSH的时候费了一番功夫,记录下来,以备忘. 配置SSH无密码登录需要3步: 1.生成公钥和私钥 ...
- SQL server 数据库测试题
- pom.xml和testng.xml
转自:http://www.cnblogs.com/penghong2014/p/4380199.html <project xmlns="http://maven.apache.or ...
- 利用PHP判断iPhone、iPad、Android、PC设备
首页那张大图确实是一个比较头疼的问题 在PC上显示是没问题的,可是到手机上就会超出页面一大截,如果做自适应,图片会被强制压缩 无奈只能用wp_is_mobile()函数在手机上隐藏了这张图,可是这函数 ...
- subclassdlgitem
subclassdlgitem 该函数用来子类化一个控件. Subclass(子类化)是MFC中最常用的窗体技术之一.子类化完成两个工作:一是把窗体类对象attach到一个windows窗体实体中(即 ...
- NullpointerException真的一定要被预防?
毫无疑问,空指针NullpointerException是我们最常遇到异常,没有之一! 在刚进入编程职业时,我想,大部分进入的同学肯定会受到前辈们的叮咛:一定要防止空指针,这是个低级错误.你们不是?好 ...
- group by where having 联合使用
having子句与where有相似之处但也有区别,都是设定条件的语句.在查询过程中聚合语句(sum,min,max,avg,count)要比having子句优先执行.而where子句在查询过程中执行优 ...
- BZOJ2163: 复杂的大门
BZOJ2163: 复杂的大门 Description 你去找某bm玩,到了门口才发现要打开他家的大门不是一件容易的事……他家的大门外有n个站台,用1到n的正整数编号.你需要对每个站台访问一定次数以后 ...
- css简单的数学运算
calc()是css3的一个新增的属性, .box{border:1px solid #ddd; width:calc(100% - 100px); background:#9AC8EB;} 兼容 ...