【题解】洛谷P1091[NOIP2004]合唱队形 线性DP

题目链接
【题解】洛谷P1091[NOIP2004]合唱队形 线性DP
【题解】洛谷P1091[NOIP2004]合唱队形 线性DP


f[i]f[i] 表示以 t[i]t[i] 结尾的最长上升子序列长度,g[i]g[i] 表示以 t[i]t[i] 开始的最长下降子序列长度
f[i]=max0j<i,t[j]<t[i]{f[j]+1}f[i]=\max\limits_{0\leq j<i,t[j]<t[i]}\{f[j]+1\}
g[i]=maxi<jn+1,t[j]<t[i]{g[j]+1}g[i]=\max\limits_{i<j\leq n+1,t[j]<t[i]}\{g[j]+1\}
初值:t[0]=t[n+1]=0t[0]=t[n+1]=0,目标:nmax1in{f[i]+g[i]1}n-\max\limits_{1\leq i\leq n}\{f[i]+g[i]-1\}

#include<cstdio>
#include<algorithm>
using namespace std;
int n,t[102],ans,f[102],g[102];
int main()
{
	//freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&t[i]);
    for(int i=1;i<=n;i++)
        for(int j=0;j<i;j++)
            if(t[j]<t[i])
			    f[i]=max(f[i],f[j]+1);
	for(int i=n;i;i--)
	    for(int j=n+1;j>i;j--)
	        if(t[j]<t[i])
	            g[i]=max(g[i],g[j]+1);
	for(int i=1;i<=n;i++)
	    ans=max(ans,f[i]+g[i]);
	printf("%d\n",n-ans+1);
	return 0;
}

总结