【p1091】【DP】【不怎么水】合唱队行

题目:链接

代码:


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int n,t[102],d1[102],d2[102],maxn=0,s=0;
int wcr(int x)
{
    int ma1=0;
        for(int i=1;i<=x;i++)//求前半段最长的上升序列长度
    {
        int max1=0;
        for(int j=1;j<i;j++)
        if(t[j]<t[i]&&d1[j]>max1) max1=d1[j];
        d1[i]=max1+1;
        if(d1[i]>=ma1) ma1=d1[i];
    }
    int ma2=0;
    for(int i=x+1;i<=n;i++)//求后半段最长的下降序列长度
    {
        int max2=0;
        for(int j=x+1;j<i;j++)
        if(t[j]>t[i]&&d2[j]>max2) max2=d2[j];
        d2[i]=max2+1;
        if(d2[i]>=ma2) ma2=d2[i];
    }
    return ma1+ma2;//求出总长度
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>t[i];
    for(int i=1;i<=n;i++)//求每个Ti时的最长长度,并求出最长储存在maxn
    {
        s=wcr(i);
        if(s>maxn) maxn=s;
    }
    cout<<n-maxn<<endl;
}

我们先看从T1到Ti这一段单调递增的序列,再看Ti到TK这一段单调递减的序列,那么问题就解决了。先从1到n求一趟最长升,然后从n到1也求一趟,最后枚举中间的Ti,然后从众多Ti中挑个大的。就解决了

猜你喜欢

转载自blog.csdn.net/sericon/article/details/94592918
今日推荐