NYOJ 17&214单调递增子序列
来源:互联网 发布:过山车大亨3 mac 编辑:程序博客网 时间:2024/05/16 12:10
NYOJ 17 214 单调递增子序列
题目链接:Click Here:17 and214
法一:简单思路
转移方程:dp[i]=dp[j]+1(a[i]>a[j]),1(a[i]<=a[j])
边界条件:dp[i]=1;
dp[j]记录a[1..j]中子序列的最长个数,dp[i]记录a[1..i]中子序列的最长个数,
当a[i]>a[j](j取值范围:0..i-1)时,dp[i]+1,
否则dp[i]=1即a[0..i-1]没有比a[i]更小的元素。
代码入下:
#include<stdio.h>#include<string.h>int p[10001];char str[10001];int main(){ int m,max; scanf("%d",&m); while(m--) { int i,j,len; scanf("%s",str); len=strlen(str); p[0]=1; for(i=1,max=1;i<len;i++) { p[i]=1; for(j=i-1;j>=0;j--) if(str[i]>str[j]&&p[i]<p[j]+1) p[i]=p[j]+1; if(max<=p[i]) max=p[i]; } printf("%d\n",max); } return 0;}
法二:利用规律
dp[len+1]=dp[len]+1(a[len+1]>a[len])
dp[len+1]=dp[j<len]+1(a[len+1]>a[j]&&a[len+1]<=a[len])在法一求解过程中可以发现,a[i]>a[i-1]时,dp[i]=dp[i-1]+1,当a[i]<=a[i-1]时,寻找第一个比a[i]小的元素位置 j,并取dp[i]=dp[j]+1,否则dp[i]=1
若用一数组表示,则相当于取得tmp[j]<a[i],tmp[j+1]位置被置为a[i]。tmp[j+1]被置为a[i]后,相当于将tmp[j+1]的值缩小,为寻找最长子序列提供保障。
比如a[i+1]>tmp[len] 则tmp[len+1]=a[i+1],len++;
若a[i+1]>tmp[j<len] 则tmp[j+1]=a[i+1],len不变。
(此处数组tmp用来存储子序列,但最后得到的存储内容,非最长子序列,需添加辅助数组。)
#include<iostream>#include <string>//#include <time.h>using namespace std;int main(){//freopen("1.txt","r",stdin);int n ;cin>>n;while(n--){string str;int count=1;cin>>str;int a[200],p[200];a[0]=-999;for (int i=0;i<str.length();i++){for (int j=count-1;j>=0;j--){if((int)str[i]>a[j]){a[j+1]=str[i];p[j+1]=i;if(j+1==count) count++;break;}}}for(int i=1;i<count;i++) cout<<(char)a[i]<<' '<<p[i]<<'\n';cout<<count-1<<endl;}
法三:借用STL中的lower_bound函数
lower_bound实例:
// lower_bound/upper_bound example#include <iostream> // std::cout#include <algorithm> // std::lower_bound, std::upper_bound, std::sort#include <vector> // std::vectorint main () { int myints[] = {10,20,30,30,20,10,10,20}; std::vector<int> v(myints,myints+8); // 10 20 30 30 20 10 10 20 std::sort (v.begin(), v.end()); // 10 10 10 20 20 20 30 30 std::vector<int>::iterator low,up; low=std::lower_bound (v.begin(), v.end(), 20); // ^ up= std::upper_bound (v.begin(), v.end(), 20); // ^ std::cout << "lower_bound at position " << (low- v.begin()) << '\n'; std::cout << "upper_bound at position " << (up - v.begin()) << '\n'; return 0;}
运行结果:
lower_bound at position 3upper_bound at position 6
lower_bound函数源码:
template <class ForwardIterator, class T> ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val){ ForwardIterator it; iterator_traits<ForwardIterator>::difference_type count, step; count = distance(first,last); while (count>0) { it = first; step=count/2; advance (it,step); if (*it<val) { // or: if (comp(*it,val)), for version (2) first=++it; count-=step+1; } else count=step; } return first;}法三源码:
#include<stdio.h>#include<algorithm>using namespace std;const int MAX=100100;int num[MAX],top;int main(){ int n,i,*p; while(scanf("%d",&n)!=EOF) { scanf("%d",&num[0]); top=1; for( i=1;i<n;i++) { scanf("%d",&num[i]); p=lower_bound(num,num+top,num[i]);//寻找 if(p-num==top) ++top; *p=num[i];//插入 } //for(i=0;i<top;i++) //printf("%d ",num[i]); printf("%d\n",top); }}
法四:二分查找
#include<stdio.h>int a[100005];int dp[100005];int binarysearth(int x,int len){int left=1,right,mid;right=len;mid=(left+right)/2;while(left<=right){if(x>dp[mid]){left=mid+1;}elseif(x<dp[mid])right=mid-1;elsereturn mid;mid=(left+right)/2;}return left;}int main(){int n;while(~scanf("%d",&n)){int i,j,len;for(i=0;i<n;i++){scanf("%d",&a[i]);}len=1;dp[1]=a[0];for(i=1;i<n;i++){j=binarysearth(a[i],len);dp[j]=a[i];if(j>len) len=j;}printf("%d\n",len);}return 0;}
单调子序列基本求解方法总结完毕。
在此基础上,可了解区间问题。
0 0
- NYOJ 17&214单调递增子序列
- NYOJ 214 单调递增子序列(二)
- NYOJ 214 单调递增子序列
- NYOJ 214 单调递增子序列(二)
- NYOJ 214 单调递增子序列二
- Nyoj 214 单调递增子序列(二)
- NYOJ 214 单调递增子序列(二)
- NYOJ 214 单调递增子序列 二
- 单调递增子序列(二)(nyoj 214)
- NYOJ 214 单调递增子序列(二)
- nyoj-214 单调递增子序列(二)
- NYOJ 214 单调递增子序列(二)
- nyoj 214单调递增子序列(二)
- NYOJ-214-单调递增子序列(二)
- NYOJ-214 单调递增子序列(二)
- NYOJ-214-单调递增子序列(二)
- nyoj 214 单调递增子序列(二)
- NYOJ-17:单调递增最长子序列
- 快速排序
- 中国34个省未来发展趋势深度分析
- SpringMVC基于注解教程(一)
- JavaScript高级程序设计 学习笔记
- 从 Empty Application 到 Single View Application
- NYOJ 17&214单调递增子序列
- c++ 时间类型详解 time_t
- Android与Linux的区别
- Please ensure that adb is correctly located at问题解决
- innobackupex在线备份及恢复(全量和增量)
- 归并排序的算法
- android中的ZoomButton源码
- C++编程命名规范
- android 之 gridview