洛谷 P1970 花匠

题目描述

花匠栋栋种了一排花,每株花都有自己的高度。花儿越长越大,也越来越挤。栋栋决定把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希望剩下的花排列得比较别致。

具体而言,栋栋的花的高度可以看成一列整数h1,h2...hn。设当一部分花被移走后,剩下的花的高度依次为g1,g2...gm,则栋栋希望下面两个条件中至少有一个满足:

注意上面两个条件在m=1时同时满足,当m>1时最多有一个能满足。

请问,栋栋最多能将多少株花留在原地。

思路

(这种算法很慢,而且比起贪心可能更难理解。但是在dp中算是最直接的一种办法

首先看到这题很容易想到LIS(最长上升子序列)

于是开两个数组表示条件a和条件b,一个整数i表示到第i个数的最大长度,并用0或1来表示接下来要选更大的还是更小的。

然后就……就TLE了。代码:

#include<iostream>

using namespace std;

int a[100005],fa[100005][2],fb[100005][2],n;

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    fa[1][0]=fb[1][0]=fa[1][1]=fb[1][1]=1;
    for(register int i=2;i<=n;i++)
    {
        for(register int j=1;j<i;j++)
        {
            if(a[j]<a[i])
            {
                fb[i][1]=max(fb[i][1],fb[j][0]+1);
                fa[i][0]=max(fa[i][0],fa[j][1]+1);
            }
            if(a[j]>a[i])
            {
                fb[i][0]=max(fb[i][0],fb[j][1]+1);
                fa[i][1]=max(fa[i][1],fa[j][0]+1);
            }
        }
    }
    cout<<max(fb[n][0],max(fa[n][1],max(fb[n][1],fa[n][0])));
    return 0;
}

但是这题不像LIS,它只需要上一个数比他小(大)就行了,只要在前面找到一个比他小的数,那就肯定表明这个数之前的序列都更短。

所以每次从后往前搜,能转移就转移。更大和更小都转移完了之后,就能够从中选取答案了。

代码:

#include<iostream>
using namespace std;

int a[100005],fa[100005][2],fb[100005][2],n;
bool flag1,flag2;

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    fa[1][0]=fb[1][0]=fa[1][1]=fb[1][1]=1;
    for(register int i=2;i<=n;i++)
    {
        flag1=flag2=1;
        for(register int j=i;j>=0&&(flag1||flag2);j--)
        {
            if(a[j]<a[i])
            {
                flag1=0;
                fb[i][1]=max(fb[i][1],fb[j][0]+1);
                fa[i][0]=max(fa[i][0],fa[j][1]+1);
            }
            if(a[j]>a[i])
            {
                flag2=0;
                fb[i][0]=max(fb[i][0],fb[j][1]+1);
                fa[i][1]=max(fa[i][1],fa[j][0]+1);
            }
        }
    }
    cout<<max(fb[n][0],max(fa[n][1],max(fb[n][1],fa[n][0])));
    return 0;
}

 

posted @ 2018-11-29 21:07  _wkjzyc  阅读(108)  评论(0编辑  收藏  举报