cugb 1009 合唱队形 (子序列)

来源:互联网 发布:工程模拟仿真软件 编辑:程序博客网 时间:2024/05/22 12:37

昨天看了好长时间还是没思路,看了别人的思路却没看懂,早上忍不住就问了老大一下(xy),嘿嘿,“因为求之后 枚举的是以某个数为顶点 左右两边最长的序列”,一语惊醒梦中人啊!还是我太笨呢?反正现在会了。。。。

第一次,求以a[i]为结束点的最长上升子序列,

第二次,求以a[i]为起始点的最长下降子序列,

这两个都求出来后,相加,那么d[i]里保存的就是每一个a[i]向两边都降的最长序列,就是某个数前边最长的升,后边最长的降,但要注意,a[i]在升序时算了一次,降序里又算了一次,故实际长度应减一,恩,就是这了。。。

#include<stdio.h> int main(){    int n,a[1005],i,j,d[1005],dp[1005],max;    scanf("%d",&n);    for(i=0;i<n;i++)       scanf("%d",&a[i]);    d[0]=1;    for(i=1;i<n;i++)    {       d[i]=1;                     for(j=0;j<i;j++)          if(a[j]<a[i]&&d[j]+1>d[i])             d[i]=d[j]+1;       }    dp[n-1]=1;    for(i=n-2;i>=0;i--)    {       dp[i]=1;                     for(j=n;j>i;j--)          if(a[j]<a[i]&&dp[j]+1>dp[i])             dp[i]=dp[j]+1;       }        for(i=0;i<n;i++)       d[i]+=dp[i];    for(i=max=0;i<n;i++)       if(max<d[i])          max=d[i];    printf("%d",n-max+1);    return 0;}      


 

原创粉丝点击