V型积木

67 阅读1分钟

2017郑州大学省赛选拔 V型积木

解题关键是大二刚学的动态规划之最长严格上升子序列,还要判断是否能摆成V型
,本题不算是很裸的算法题

10503: V型积木

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 146   Solved: 14
[ Submit][ Status][ Web Board]

Description

  Dr.Wu的宝宝1岁了,所以Dr.Wu准备买些积木给宝宝玩,促进孩子大脑的发育。由于宝宝太小,所以他将高低不同的积木摆放的毫无规律(如图A)。然而Dr.Wu发现,如果从当前的积木中抽走一部分(图B,C中虚线的即表示抽走的积木),剩下的积木能够呈现出“V”形,即积木的高度先 严格 递减,然后 严格 递增。图B中,需要抽走三个积木,剩下的积木就可以呈现出“V”形,而图C中仅需抽走一根积木。Dr.Wu需要你帮忙找出最少抽走多少积木,剩下的积木就能呈现出“V”型?

Input

第一行:  T     表示以下有T组测试数据( 1≤ T  ≤ 8)

对每组测试数据:

第一行:    N表示积木的个数。 ( 2<N<=100 ),

第二行是空格隔开的N个正整数,每个正整数Hi表示第i个积木的高度(0<Hi<=10000)。

输出中,仅一个数,即最少抽走的积木数。如果怎么抽走积木都无法呈现出“V”形,则输出“No Solution”。

Output

每组测试数据,输出占一行, 仅一个数,即最少抽走的积木数。如果怎么抽走积木都无法呈现出“V”形,则输出“No Solution”。

Sample Input

2
6
50  30  40  10  20  60
6
5  4  3  1  2  6

Sample Output

1
0
#define _CRT_SECURE_NO_WARNINGS
#include <iostream> 
#include <cstdio> 
#include <map> 
#include <set> 
#include <stack> 
#include <queue> 
#include <cmath> 
#include <cstdlib> 
#include <algorithm> 
#include <string> 
#include <cstring> 
#include <climits> 
using namespace std;
const int maxn = 1e2 + 7;
int ary[maxn];
int aryInt[maxn];
int LIS(int aryInt[], int n) {
	int dp[107];
	dp[0] = INT_MIN;
	dp[1] = aryInt[0];
	int nMaxLis = 1;
	for (int i = 1; i< n; ++i) {
		int j = (int)(lower_bound(dp, dp + nMaxLis + 1, aryInt[i]) - dp);
		if (j > nMaxLis) {
			nMaxLis = j;
			dp[j] = aryInt[i];
		}
		else if (dp[j - 1] < aryInt[i] && aryInt[i] < dp[j])
			dp[j] = aryInt[i];
	}
	return nMaxLis;
}
int main()
{
	int t;
	scanf("%d", &t);
	while (t--) {
		int n;
		scanf("%d", &n);
		for (int i = 0; i < n; ++i)
			scanf("%d", ary + i);
		int ans = INT_MAX;
		int i, Min = ary[0];
		bool flag = false;
		for (i = 1; i < n - 1; ++i) {
			if (ary[i] < Min && ary[i] < ary[i + 1]) {
				flag = true;
				break;
			}
			else {
				Min = min(Min, ary[i]);
			}				
		}
		if (!flag) {
			cout << "No Solution" << endl;
			continue;
		}
		for (int i = 1; i <= n - 2; ++i) {
			int cnt = 0;
			for (int l = 0; l < i; ++l) {
				if (ary[l] > ary[i])
					aryInt[cnt++] = -ary[l];
			}
			aryInt[cnt++] = -ary[i];
			for (int r = i + 1; r < n; ++r)
				if (ary[r] > ary[i])
					aryInt[cnt++] = ary[r];
			ans = min(ans, n - LIS(aryInt, cnt));
		}
		cout << ans << endl;
	}

	return 0;
}
// wjqin

\

\

\

\