洛谷 - 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一个个读入.判断.累加,最后输出即可. 不过 ...
随机推荐
- 一个能自己主动搜索源文件并自己主动推导的Makefile
今天看了一天的makefile的写法.东拼西凑.好不easy写出了一个makefile.颇有成就感,记录下来,以备温习之用. 如果有两个头文件文件夹 header1,header2;两个cpp文件文件 ...
- eclipse 配置执行hadoop 2.7 程序样例參考步骤
前提:你搭建好了hadoop 2.x的linux环境,并可以成功执行.还有就是window可以訪问到集群.over 1. hfds-site.xml 添加属性:关闭集群的权限校验.windows的用户 ...
- SQL获取事件探查器保存的跟踪文件
fn_trace_gettable (Transact-SQL) 以表格格式返回一或多个跟踪文件的内容. Transact-SQL 语法约定 语法 fn_trace_gettable ( filena ...
- CF 568A(Primes or Palindromes?-暴力推断)
A. Primes or Palindromes? time limit per test 3 seconds memory limit per test 256 megabytes input st ...
- mybatis 简单项目步骤
mybatis.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configura ...
- 三张图教你生成一个Android jar 库。
我看到非常多教人使用第三方开源组件的Android教程.都是在教基于源代码project的库导入,个人觉得非常不妥,觉得最恰当的方式是把源代码project生成一个jar再导入到目标project上使 ...
- c# 扩展方法奇思妙用基础篇五:Dictionary<TKey, TValue> 扩展
Dictionary<TKey, TValue>类是常用的一个基础类,但用起来有时确不是很方便.本文逐一讨论,并使用扩展方法解决. 向字典中添加键和值 添加键和值使用 Add 方法,但很多 ...
- 通过反射获取java nio Direct Memory 的最大值和已使用值
(ps:jdk1.7及之后可通过MBean获取这两个值)
- POJ2942 Knights of the Round Table 点双连通分量 二分图判定
题目大意 有N个骑士,给出某些骑士之间的仇恨关系,每次开会时会选一些骑士开,骑士们会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件:1.任意相互憎恨的两个骑士不能相邻.2.开会人数为大于2的奇 ...
- pyenv 安装本地版本
最近在用pyenv安装python的时候发现官网特别慢,经常出现拒绝访问的情况.看了一些解决方法,发现可以使用本地的python源码进行安装,让pyenv从本地下载就可以了~步骤如下: 首先从官网下载 ...