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. [Tools] Region commands to collapse the code by group

    For a file which contians lots of lines of code, we can use 'comments region' to collapse the code. ...

  2. 三期_day05_Dao层的准备工作_II

    工作文件夹: 实体类:UserInfo.java package com.yc.crm.entity; import java.util.Date; public class UserInfo { p ...

  3. Android菜单menu控件大全

    下载:http://www.see-source.com/androidwidget/list.html?type=16 Android-NewPopupMenu 使用PopupWindow实现的Po ...

  4. IOS Object和javaScript相互调用

    在IOS开发中有时会用到Object和javaScript相互调用,详细过程例如以下: 1. Object中运行javascript代码,这个比較简单,苹果提供了非常好的方法 - (NSString ...

  5. 常见iOS面试题 之 怎么判断一个类是否遵循某个协议

    答案: 使用方法conformsToProtocol. 调用例子: BOOL isConform = [Student conformsToProtocol:@protocol(UIScrollVie ...

  6. 笨鸟不乖 是这么设计Android项目架构的

    项目地址:https://github.com/benniaobuguai/android-project-wo2b部分效果图        项目结构当前项目只是其中一个例子,wo2b-common- ...

  7. Allegro改动shape网络节点

    使用Allegro时改动shape的网络节点方法: ①选择shape->Select Shape or Void/Cavity ②选择要改动的shape ③点击(...)改动网络节点的名字 ④改 ...

  8. C3P0连接池配置和实现详解(转)

    一.配置 <c3p0-config> <default-config> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数.Default: 3 --> ...

  9. for in 与for of

    最近在项目中需要用到遍历对象,用ES6 for of对象后报如下错误  TypeError: [object Object] is not iterable!,网上查询阮大神的教程发现“ES6 的有些 ...

  10. String、StringBilder和StringBuffer之间的区别

    1.三者在执行速度方面的比较:StringBuilder >  StringBuffer  >  String 2.String <(StringBuffer,StringBuild ...