UVa 10534 Wavio Sequence

来源:互联网 发布:女生发型 知乎 编辑:程序博客网 时间:2024/05/02 04:48

UVa  10534  Wavio Sequence              题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=17&problem=1475&mosmsg=Submission+received+with+ID+13120764

DP LIS

题目大意:有一种叫做Wavio的序列,满足先升后降(就是↗↘这个形状)且前后等长。在给出数列中找最长的这种Wavio序列,输出其长度。

题目分析:找这样的最长序列可分两步走,先求LIS和LDS(遍历每一个点,求起点到当前点的LIS和当前点到终点的LDS,分别存在数组里);再对LIS和LDS序列对应元素求最小值(等长),求出所得序列的最大值(最长)。注意找到之后要乘二再减一才能得到总序列长。

code:

#include<stdio.h>const int maxl=10011,inf=2147483647;int dp[maxl],n;int binary(int x){int l=0,r=n-1,mid;while(l<r){mid=(l+r)>>1;if(dp[mid+1]>=x)r=mid;else l=mid+1;}return l;}void dpclear(){int i;for(dp[0]=-inf-1,i=1;i<n;i++)dp[i]=inf;}int min(int a,int b){return a<b?a:b;}int max(int a,int b){return a>b?a:b;}int main(){int i,lis[maxl],lds[maxl],a[maxl];while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++)scanf("%d",&a[i]);dpclear();for(i=0;i<n;i++){lis[i]=binary(a[i])+1;if(a[i]<dp[lis[i]])dp[lis[i]]=a[i];}dpclear();for(i=n-1;i>=0;i--){lds[i]=binary(a[i])+1;if(a[i]<dp[lds[i]])dp[lds[i]]=a[i];}int ans=0;for(i=0;i<n;i++)ans=max(ans,min(lis[i],lds[i]));printf("%d\n",2*ans-1);}return 0;}
PS:现在还在学习阶段,刚看到题目中Wavio序列定义的时候有点蒙,没有想到可以转化成LIS来做。拿这题是为了学LIS二分做法,花了一天多时间总算有所收获。现在LIS二分出了两道题了,存下增序序列的思路已经清晰。不管是LIS、LDS还是推广到更一般的情况(L符合某种要求的S),其核心思路(状态转移)都一样,二分优化也一样。




0 0
原创粉丝点击