花匠(动态规划)

花匠

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

具体而言,栋栋的花的高度可以看成一列整数 h_1,h_2,…,h_n 。设当一部分花被移走后,剩下的花的高度依次为 g_1,g_2,…,g_m,则栋栋希望下面两个条件中至少有一个满足:
条件 A:对于所有 g{2i} > g{2i-1},g{2i} > g{2i+1}
条件 B:对于所有 g{2i} < g{2i-1},g{2i} < g{2i+1}
注意上面两个条件在 m=1m=1 时同时满足,当 m > 1m>1 时最多有一个能满足。请问,栋栋最多能将多少株花留在原地。
输入输出格式
输入格式:
第一行包含一个整数 n ,表示开始时花的株数。
第二行包含 n个整数,依次为 h1,h2,…,hn,表示每株花的高度。
输出格式:
一个整数 m,表示最多能留在原地的花的株数。

题解:
对于这道题我只能说我智商不够,虽然一眼看就知道怎么做,但是一开始想到的是n方DP。肯定得不到满分。

先给n方的题解:
f[i][j]表示第i个数字是当前以j为顺序的末尾的最大值。
相当easy
代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=100010;

int a[maxn],f[maxn][3],n,m;

int main()
{
    freopen("flower.in","r",stdin);
    freopen("flower.out","w",stdout);
    scanf("%d",&n);
    for (int i=1; i<=n; i++)
      {
        scanf("%d",&a[i]);
        f[i][0]=1;
        f[i][1]=1;
      }
    for (int i=1; i<=n; i++)
      for (int j=i+1; j<=n; j++)
        {
            if (a[j]>a[i]) f[j][0]=max(f[j][0],f[i][1]+1);
            if (a[j]<a[i]) f[j][1]=max(f[j][1],f[i][0]+1);
        }
    int ans=0;
    for (int i=1; i<=n; i++)
      {
        ans=max(ans,f[i][0]);
        ans=max(ans,f[i][1]);
      }
    cout<<ans;
}

O(n)算法
智商不够,
完全不需要n方的嘛,如果可以作为升序就升序算,不能升序就直接把前一个值过继来 嘛(降序亦然)
轻松a的!!!!!

#include<bits/stdc++.h>
using namespace std;
const int maxn=100001;

int a[maxn],g[maxn][2]={0};
int n;
int main(){
    freopen ("flower.in","r",stdin);
    freopen ("flower.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);} 
    g[1][0]=g[1][1]=1;
    for(int i=2;i<=n;i++){
        if(a[i]>a[i-1]){
            g[i][0]=g[i-1][1]+1;
        }else{
            g[i][0]=g[i-1][0];  }
        if(a[i]<a[i-1]){
            g[i][1]=g[i-1][0]+1;
        }else{
            g[i][1]=g[i-1][1];
        }
    }
    cout<<max(g[n][0],g[n][1]);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/beautiful_cxw/article/details/80985244