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的更多相关文章

  1. 洛谷P1118 数字三角形游戏

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

  2. 洛谷P1118 数字三角形【dfs】【STL】

    题目链接:https://www.luogu.org/problemnew/show/P1118 题意: 1~n的一个排列,相邻的两项加起来得到下一行. 现在给定最后一行的数字,问最初的1~n的排列是 ...

  3. 洛谷 P1118 数字三角形游戏 Label:dfs

    题目描述 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置.下面是一 ...

  4. 洛谷P1118数字三角形题解

    题目 这个题我们乍一看会有些熟悉.觉得是可以用DP来做的那个题.但是打眼一看,就会发现不对了.因为那个题是顺推而这个题则是逆推. 这样的话可怎么办呢. 我们可以在草稿纸上推一下,我们随便写个数n. 再 ...

  5. 洛谷P1216 数字三角形【dp】

    题目:https://www.luogu.org/problemnew/show/P1216 题意: 给定一个三角形.从顶走到底,问路径上的数字之和最大是多少. 走的时候可以往左下(实际上纵坐标不变) ...

  6. 洛谷P1216数字三角形题解

    题目 这道题是一个典型的DP,可以用倒推,顺推的方法,来解这道题.当然用不同的方法他的循环次序是不一样的,所以我们一定要深刻地理解题目的大意,再采用状态转移方程与边界每次求出最优解,并记录循环一遍后就 ...

  7. 洛谷P1553 数字翻转(升级版)

    题目链接 https://www.luogu.org/problemnew/show/P1553 题目描述 给定一个数,请将该数各个位上数字反转得到一个新数. 这次与NOIp2011普及组第一题不同的 ...

  8. 【洛谷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 ...

  9. 洛谷 P5660 数字游戏 & [NOIP2019普及组]

    传送门 洛谷改域名了QAQ 解题思路 没什么好说的,一道红题,本不想发这篇博客 ,但还是尊重一下CCF吧QAQ,怎么说也是第一年CSP呢! 用getchar一个个读入.判断.累加,最后输出即可. 不过 ...

随机推荐

  1. Android新技术学习——阿里巴巴免Root无侵入AOP框架Dexposed

    阿里巴巴无线事业部近期开源的Android平台下的无侵入运行期AOP框架Dexposed,该框架基于AOP思想,支持经典的AOP使用场景.可应用于日志记录,性能统计,安全控制.事务处理.异常处理等方面 ...

  2. 如何干掉那些.ipch 与 .sdf文件

    参考资料: http://blog.163.com/yangjun1988422@126/blog/static/47412917201074446054/     vs2010中臃肿的ipch和sd ...

  3. 作为iOS程序员,最核心的60%能力有哪些?

    作为iOS程序员,最核心的60%能力有哪些?   一个合格的iOS程序员需要掌握多少核心技能?你和专业的开发工程师的差距有多大?你现在的水平能开发一个功能完整性能高效的iOS APP吗?一起来看看下面 ...

  4. 基于PHP函数的alert弹框

    可以设置弹出信息,跳转地址,跳转的时间,跳转的信息标题提示: 手机端加上<meta name='viewport' content='width=device-width, initial-sc ...

  5. 新拿到的app跑的时候出现问题

    连接器链接失败,是因为对应类build后的中间产物.o文件没有生成,对应架构下,用模拟器跑的,很可能是因为无法编译产出x86,或i386架构的中间产物,所以linker链接转换机器码时候找不到对应的中 ...

  6. CH 5102 Mobile Service(线性DP)

    CH 5102 Mobile Service \(solution:\) 这道题很容易想到DP,因为题目里已经说了要按顺序完成这些请求.所以我们可以线性DP,但是这一题的状态不是很好设,因为数据范围有 ...

  7. springboot和redis处理页面缓存

    页面缓存是应对高并发的一个比较常见的方案,当请求页面的时候,会先查询redis缓存中是否存在,若存在则直接从缓存中返回页面,否则会通过代码逻辑去渲染页面,并将渲染后的页面缓存到redis中,然后返回. ...

  8. Notepad++文本编辑器 快捷键

    Ctrl+C 复制Ctrl+X 剪切Ctrl+V 粘贴Ctrl+Z 撤消Ctrl+Y 恢复Ctrl+A 全选Ctrl+F 键查找对话框启动Ctrl+H 查找/替换对话框Ctrl+D 复制并粘贴当行 C ...

  9. local_irq_disable

    local_irq_disable 仅仅是 设置 当前CPU 的中断屏蔽位 disable_irq 是禁用 全部cpu 中断(只是当前irq) 如果你要禁止所有的中断该怎么办? 在2.6内核中,可以通 ...

  10. 通过ODC方法改善软件测试:3个案例研究

    正交缺陷分类法(ODC)是一种用于分析软件缺陷的归类方法.它可以结合软件开发过程的一系列数据分析技术,为测试组织提供了一个强大的针对开发过程和软件产品的评估方法.在本篇文章中,会列举三个案例研究来说明 ...