https://www.luogu.org/problemnew/show/P1118

next_permutation的第二个参数是最后一个元素的下一个元素,sort也是一样!有毒!这么低级的错误。而且应该是用do_while因为原始排列也要考虑!

使用sort跳过一些permutation的原理来源于:

1.假设解存在,那么对称位置的两个元素交换也是一种解

2.我们要求第一种解,必定是左边元素小于右边对应元素的

3.当某个排列导致当前大于sum,怎么证明发现该元素之后的任意排列都是大于sum的呢?

4.假如发现该元素的位置在中间的右侧,那么把更大的元素前移只会让答案变大

5.假如发现该元素的位置在中间的左侧,若这其中有解,必定在之前已经搜索过对应位置的了。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define ll long long
  4. /*
  5. int N,sum;
  6.  
  7. int cntn[13];
  8.  
  9. int solve(vector<int> &cur,vector<int> &next,int nf){
  10. next.clear();
  11. next.push_back(nf);
  12.  
  13. int pre=nf;
  14. int sz=cur.size();
  15. for(int i=0;i<sz;i++){
  16. int tmp=cur[i]-pre;
  17. if(tmp<=0)
  18. return 0;
  19. next.push_back(tmp);
  20. pre=tmp;
  21. }
  22. return 1;
  23. }
  24.  
  25. void dfs(int n,vector<int> cur){
  26. if(n==N){
  27. //wrong, maybe N+1
  28. int sz=cur.size();
  29. memset(cntn,0,sizeof(cntn));
  30.  
  31. for(int i=0;i<sz;i++){
  32. if(cur[i]>n||cntn[cur[i]])
  33. return;
  34. else{
  35. cntn[cur[i]]++;
  36. }
  37. }
  38.  
  39. for(int i=0;i<sz;i++){
  40. printf("%d%c",cur[i]," \n"[i==sz-1]);
  41. }
  42. exit(0);
  43. }
  44. else{
  45. vector<int> next;
  46. for(int nextfirst=1;nextfirst<=cur[0]-1;nextfirst++){
  47. int suc=solve(cur,next,nextfirst);
  48. if(suc){
  49. dfs(n+1,next);
  50. }
  51. else{
  52. ;
  53. }
  54. }
  55. }
  56. }
  57.  
  58. int main(){
  59. scanf("%d%d",&N,&sum);
  60. vector<int> v;
  61. v.push_back(sum);
  62. dfs(1,v);
  63. }
  64.  
  65. */
  66. int N,sum;
  67.  
  68. int ans[][];
  69. int pas[][];
  70.  
  71. inline int findsum(){
  72. /*for(int i=2;i<=N;i++){
  73. for(int j=1;j<=N+1-i;j++){
  74. ans[i][j]=ans[i-1][j]+ans[i-1][j+1];
  75. if(ans[i][j]>sum)
  76. return -1;
  77. }
  78. }*/
  79. int tmp=;
  80. for(int i=;i<=N;i++){
  81. //printf("%d ",pas[N][i]);
  82. tmp+=pas[N][i]*ans[][i];
  83. if(tmp>sum){
  84. sort(&ans[][i],&ans[][N]+,greater<int>());
  85. //因为nextpermutation绝对会把大的数字前移,
  86. //根据对称性我们会优先得到小的解,也就是这个不会过半
  87. //所以下一次nextpermutation绝对是会变大的
  88. return -;
  89. }
  90. }
  91. //printf("\n");
  92. //cout<<"tmp="<<tmp<<endl;
  93. return tmp;
  94. }
  95.  
  96. int main(){
  97. scanf("%d%d",&N,&sum);
  98.  
  99. /*if(N<=2){
  100. if(N==1){
  101. if(sum==1){
  102. printf("1\n");
  103. }
  104. }
  105. else{
  106. if(sum==3){
  107. printf("1 2\n");
  108. }
  109. }
  110. return 0;
  111. }*/
  112.  
  113. for(int i=;i<=N;i++){
  114. ans[][i]=i;
  115. }
  116.  
  117. pas[][]=;
  118. //printf("1\n");
  119. for(int i=;i<=N;i++){
  120. pas[i][]=pas[i][i]=;
  121. for(int j=;j<=i-;j++)
  122. pas[i][j]=pas[i-][j]+pas[i-][j-];
  123. /*for(int j=1;j<=i;j++){
  124. printf("%d ",pas[i][j]);
  125. }
  126. printf("\n");*/
  127. }
  128.  
  129. /*for(int i=1;i<=N;i++){
  130. printf("%d ",pas[N][i]);
  131. }
  132. printf("\n");*/
  133.  
  134. do{
  135. if(sum==findsum()){
  136. for(int i=;i<N;i++){
  137. printf("%d%c",ans[][i+]," \n"[i==N-]);
  138. }
  139. break;
  140. }
  141. else{
  142. /*for(int i=0;i<N;i++){
  143. printf("%d%c",ans[1][i+1]," \n"[i==N-1]);
  144. }*/
  145. }
  146. }while(next_permutation(&ans[][],&ans[][N]+));
  147. }

洛谷 - 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. 【J2EE】十三个规范:愿天下苍生,人人如猿。

    学习了J2ee后对java这个立足标准化的行为感到深深的佩服. 收买什么都不如收买人心,培养啥子都不如培养 习惯.没错,java就是在培养行业习惯,以一纸规范屹立不倒.毕竟技术什么的层出不穷,再新再前 ...

  2. [Testing] Config jest to test Javascript Application -- Part 3

    Run Jest Watch Mode by default locally with is-ci-cli In CI, we don’t want to start the tests in wat ...

  3. STL源代码分析--deque

    一.deque的中控器       deque是连续空间(至少逻辑上看来如此),连续线性空间总令我们联想到array或vector.array无法成长,vector虽可成长,却仅仅能向尾端成长.并且其 ...

  4. zoj How Many Shortest Path

    How Many Shortest Path 题目: 给出一张图,求解最短路有几条.处理特别BT.还有就是要特别处理map[i][i] = 0,数据有不等于0的情况! 竟然脑残到了些错floyd! ! ...

  5. 手写 redux 和 react-redux

    1.手写 redux redux.js /** * 手写 redux */ export function createStore(reducer) { // 当前状态 let currentStat ...

  6. 创建节点createElement

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  7. 前端编程提高之旅(五)----写给大家看的css书

       自实习也有几个月的时间了,以爱奇艺实习为敲门砖.进入了眼下这家公司.假设说当初能进爱奇艺是暂时袭击DIV+CSS的话,眼下在这家公司体验到.不论什么技术都必须悉知原理,这样才干做到庖丁解牛.做一 ...

  8. PostgreSQL 源码解读 node的模拟实现

      node的实现是PostgreSQL的查询解析的基础,实现的关键是两个宏,makeNode和newNode.其他节点继承自Node节点,如果增加新的结构体,需要添加NodeTag中添加对应的枚举值 ...

  9. spring mvc带参数重定向

    http://blog.csdn.net/jackpk/article/details/19121777/ https://isudox.com/2017/02/16/spring-mvc-redir ...

  10. jconsole工具检测堆内存变化的使用

    jconsole将Java写的程序检测. 从Java 5开始 引入了 JConsole.JConsole 是一个内置 Java 性能分析器,可以从命令行或在 GUI shell 中运行.您可以轻松地使 ...