analysis
来源:互联网 发布:javascript冒泡排序 编辑:程序博客网 时间:2024/04/19 11:20
analysis
Time Limits: 1000 ms Memory Limits: 128000 KB
Description
给你N个数字,将其分成若干子序列,每个序列都必须是递增或递减的.
希望子序列的数量越少越好。
Input
本题有多组数据
对于每组数据,第一行一个整数N
第二行N个整数Ai.
Output
对于每组数据,输出最少的个数
Sample Input
1531 3 2
Sample Output
12
Hint
数据范围
N<=50
保证Ai中的数字不重复,且0<=Ai<=200
每个输入文件中不超过10组数据
提示
对于Pascal选手,推荐使用seekeof判断文件结束
》》题目感知:题目太码农,解法太玄学!!
总而言之,题目出得有点过于坑
解题思路
主要算法就是搜索,直接暴力,枚举(或二分)答案,然后再深搜迭代加深。
设tot1表示为降序列的个数,tot2表示为升序列的个数,Ui表示为第i个生序列的队首,Di表示为第i个降序列的队首。
有如下几种操作:
- 若tot2=0,新开一个U存入当前的数,深搜一遍;
- 若tot1=0,新开一个D存入当前的数,深搜一遍;
- 若tot1>0且存在Di>当前的数,让当前的数存入符合条件的Di中最小的序列,深搜一遍;
- 若tot2>0且存在Ui<当前的数,让当前的数存入符合条件的Ui中最大的序列,深搜一遍;
- 若tot1>0但不存在Di>当前的数,新开一个D存入当前的数,深搜一遍;
- 若tot2>0但不存在Ui<当前的数,新开一个U存入当前的数,深搜一遍。
注意,一定要按照这种顺序(除非你打得十分优美),否则会TLE,至于为什么,我也不知道。同时,注意一下输入,非常坑。这就是我为什么说“》》题目感知:题目太码农,解法太玄学!!”的原因了。
Codes:
#include<cstdio>#include<cstring>#include<cmath>#define fo(i,x,y) for(int i=x;i<=y;i++)using namespace std;int n,a[51],mid,tot1,tot2,U[51],D[51];char num;bool q;void can(int);int main(){ for(;;)//相当于while(1) { num=getchar(); if(num<'0' || num>'9')break; int x=num-'0'; for(;;) { num=getchar(); if(num<'0' || num>'9')break; x+=x*9+(num-'0'); } fo(i,1,x)scanf("%d",&a[i]); scanf("\n"); n=x; int l=1,r=floor(sqrt(n)),ans=r;/*枚举到√n即可,易证*/ while(l<=r) //二分 { mid=(l+r)>>1; q=0; tot1=tot2=0; can(1); if(q) { r=mid-1; ans=mid; }else{ l=mid+1; } } printf("%d\n",ans); } }void can(int w)/*搜索顺序很关键*/{ bool p=0,o=0; int wz,s,z; if(tot1+tot2>mid)return; if(w>n){q=1;return;} if(tot2==0) { U[++tot2]=a[w]; can(w+1);if(q)return; tot2--;/*这里一定不要丢掉*/ } if(tot1==0) { D[++tot1]=a[w]; can(w+1);if(q)return; tot1--;/*这里一定不要丢掉*/ } if(tot1>0) { z=0x7fffffff; for(int i=1;i<=tot1;i++) { if(D[i]>a[w] && D[i]<z) { z=D[i];wz=i; } } if(z<0x7fffffff) { s=D[wz]; D[wz]=a[w]; can(w+1);if(q)return; D[wz]=s;/*这里一定不要丢掉*/ }else p=1; } if(tot2>0) { z=-1; for(int i=1;i<=tot2;i++) { if(a[w]>U[i] && U[i]>z) { z=U[i];wz=i; } } if(z>-1) { s=U[wz]; U[wz]=a[w]; can(w+1);if(q)return; U[wz]=s;/*这里一定不要丢掉*/ }else o=1; } if(p) { D[++tot1]=a[w]; can(w+1);if(q)return; tot1--; /*这里一定不要丢掉*/ } if(o) { U[++tot2]=a[w]; can(w+1);if(q)return; tot2--;/*这里一定不要丢掉*/ }}
这些“/这里一定不要丢掉/”,重要的事说三遍,这里说六遍,脑补一下
1 0
- analysis
- analysis
- analysis
- FlexStore Analysis
- Image Analysis
- NUMERICAL ANALYSIS
- obj analysis
- Requirements analysis
- GAP Analysis
- code analysis
- data analysis
- Data Analysis
- finally analysis
- Register Analysis
- blat analysis
- Analysis VB
- scoped_ptr analysis
- malware-analysis
- dp和px的相互转化
- 马尔可夫模型与条件随机场模型
- 7.14
- Python爬虫入门
- 文件系统
- analysis
- 手机终端UA信息收集------- X-WAP-PROFILE
- JavaScript网页计算器
- Java之@SuppressWarnings注解
- 第144课: Spark面试经典系列之NULL值问题及序列化错误
- java的相关资料
- wiki_word2vec_python实验
- Java_day07
- 【OpenCV笔记 06】OpenCV中绘制基本几何图形【矩形rectangle()、椭圆ellipse() 、圆circle() 】