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

2023-02-12,,

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

枚举每本书作为最低点时的情况

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
int cal_1[110],cal_2[110];
int Dp(int a[], int len)
{
int dp[110] = { 0 };
int cnt = 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);
cnt = max(cnt, dp[i]);
}
}
return cnt;
}
int main()
{
int T;
while (~scanf("%d", &T))
{
while (T--)
{
int flag = 0;
int m;
scanf("%d", &m);
for (int i = 0; i < m; i++)
{
scanf("%d", &cal_1[i]);
cal_2[m - i - 1] = cal_1[i];
}
int cnt=-1;
for (int i = 1; i < m-1; i++)
{
int down = Dp(cal_2 + m - i - 1, i + 1);//正向
int up = Dp(cal_1 + i, m - i);//反向
if (down == 1 || up == 1)//只有一本时无法构成V型
continue;
cnt = max(cnt, down + up - 1);
}
if (cnt == -1)
cout << "SAD" << endl;
else
cout << "HAPPY" << endl << m-cnt << endl;
}
}
return 0;
}
/**********************************************************************
Problem: 1560
User: leo6033
Language: C++
Result: AC
Time:68 ms
Memory:2024 kb
**********************************************************************/

CSUOJ 1560 图书管理员的表白方式的相关教程结束。

《CSUOJ 1560 图书管理员的表白方式.doc》

下载本文的Word格式文档,以方便收藏与打印。