昨天看了好长时间还是没思路,看了别人的思路却没看懂,早上忍不住就问了老大一下(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;
}