导弹防御系统
为了对抗附近恶意国家的威胁,R 国更新了他们的导弹防御系统。
一套防御系统的导弹拦截高度要么一直 严格单调 上升要么一直 严格单调 下降。
例如,一套系统先后拦截了高度为 3 和高度为 4 的两发导弹,那么接下来该系统就只能拦截高度大于 4 的导弹。
给定即将袭来的一系列导弹的高度,请你求出至少需要多少套防御系统,就可以将它们全部击落。
输入格式
输入包含多组测试用例。
对于每个测试用例,第一行包含整数 n,表示来袭导弹数量。
第二行包含 n 个不同的整数,表示每个导弹的高度。
当输入测试用例 n=0 时,表示输入终止,且该用例无需处理。
输出格式
对于每个测试用例,输出一个占据一行的整数,表示所需的防御系统数量。
数据范围
1≤n≤50
输入样例:
5
3 5 2 4 1
0
输出样例:
2
样例解释
对于给出样例,最少需要两套防御系统。
一套击落高度为 3,4 的导弹,另一套击落高度为 5,2,1 的导弹。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 51;
int num[N];//高度数组
int n;//导弹个数
int f[N];//贪心的下降子序列的末尾元素
int g[N];//贪心的上升子序列的末尾元素
int cnt;//需要的系统数
void dfs(int it, int us, int ds)//dfs深搜
{
if (us + ds >= cnt)return;//剪枝
if (it == n) {
cnt = us + ds;//找到一种方案更新一下系统数
return;
}
//不断下降的深搜,贪心
int k = 0;
while (k<us && f[k]>=num[it])k++;
int t = f[k];
f[k] = num[it];
if (k >= us)dfs(it + 1, us + 1, ds);
else dfs(it + 1, us, ds);
f[k] = t;//还原元素,为了下次深搜
//不断上升的深搜,贪心
k = 0;
while (k < ds && g[k] <= num[it])k++;
t = g[k];
g[k] = num[it];
if (k >= ds)dfs(it + 1, us, ds + 1);
else dfs(it + 1, us, ds);
g[k] = t;
}
int main()
{
while (cin >> n, n) {
for (int i = 0; i < n; i++)cin >> num[i];
cnt = n;
dfs(0, 0, 0);
printf("%d\n", cnt);
}
}

浙公网安备 33010602011771号