CSU 1560 图书管理员的表白方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lizhaowei213/article/details/51165761

1560: 图书管理员的表白方式

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 114   Solved: 36
[ Submit][ Status][ Web Board]

Description

小V是中南大学图书馆的图书管理员,每天要整理很多同学们还回来的书。久而久之,他认识了很多常来图书馆的同学,比如说小L。简而言之吧,就是小V喜欢上了小L,并且想在下一次她来还书的时候表白。
小V的创意还是不错的,他精心准备了各种材料,打算构成“L”,“O”,“V”,“E”四个字母,在小L来的时候悄悄组合起来给她看。但是意外来了:在小L来的时候,小V只准备好了“L”,“O”,和“E”,“V”还没有拼好!但是机智的小V立刻想到了一个办法:他可以随手把旁边别人还的书合在一起,并且抽掉其中一部分,令剩下的书的高度构成了一个“V”形。
那么问题来了:已知N本书的高度,在不改变他们的顺序的前提下,能不能得到小V想要的“V”,如果可以的话,最少去掉多少本书呢?
(组成“V”的前提:h1>h2...<hn,即整个高度必须先递减再递增)

Input


多组数据,第一行有一个整数T,表示有T组数据。(T<=100
以下每组数据第一行有一个整数N,表示这一排书的数量。(1<=N<=100)
然后接下来一行是N个整数,h1,h2...hn分别代表每本书的高度。(1<=hi<=100)

Output

如果可以构成”V”,输出“HAPPY”,并在下一行输出所需拿掉的最少数量。
如果不能,输出“SAD”。

Sample Input

7
3
3 2 3
4
3 2 4 3
5
1 2 4 6 7
1
22
2
25 8
3
98 16 68
4
88 14 82 69

Sample Output

HAPPY
0
HAPPY
1
SAD
SAD
SAD
HAPPY
0
HAPPY
1

HINT


最长上升子序列变形题。

假设数组编号0-n-1
方法就是枚举1-n-2的位置作为中间位置的情形下,求ret=左侧的最长下降子序列+右侧最长上升子序列
如果其中有一个=1,那么意味着有一侧是不下降或不上升的,此时不符合题目要求,直接continue就好

#include <stdio.h>
#include <algorithm>
using namespace std;
const int MAXN=105;
int nums[MAXN];
int numsRe[MAXN];
int getDp(int a[],int len)
{
        int dp[MAXN]={0};
        int ret=1;
        for(int i=0;i<len;i++)
        {
                dp[i]=1;
                for(int j=0;j<i;j++)
                        if(a[i]>a[j])
                                dp[i]=max(dp[i],dp[j]+1);
                ret=max(ret,dp[i]);
        }
        return ret;
}

int main()
{
        int t;
        scanf("%d",&t);
        while(t--)
        {
                int n;
                scanf("%d",&n);
                for(int i=0;i<n;i++)
                {
                        scanf("%d",&nums[i]);
                        numsRe[n-i-1]=nums[i];
                }
                int ret=-1;
                for(int i=1;i<n-1;i++)
                {
                        int down=getDp(numsRe+n-i-1,i+1);
                        int up=getDp(nums+i,n-i);
                        if(down==1||up==1)
                                continue;
                        ret=max(down+up-1,ret);
                }
                if(ret==-1)
                        printf("SAD\n");
                else
                        printf("HAPPY\n%d\n",n-ret);
        }
        return 0;
}


猜你喜欢

转载自blog.csdn.net/lizhaowei213/article/details/51165761