dengch

 

导弹防御系统

题目概述:现在R国更新了导弹防御系统,使得该系统拦截的导弹高度要么是严格上升的,要么是严格下降的。问拦截所有导弹至少需要多少套系统
解题思路:在拦截导弹一题的基础上,多引入了一个选择:导弹是归为上升子序列,还是下降子序列。可以使用dfs直接暴力枚举所有选择,当然中间会有剪枝。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#include <vector>
#include <map>
#include <set>

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;
const int N = 5010;

int h[N];
int up[N],down[N];
int dp[N];
int n,ans;

//参数意义:
//u:枚举的点数
//su:上升子序列中数的数量
//sd:下降子序列中数的数量
void dfs(int u,int su,int sd){
	//剪枝操作
	if(sd + su >= ans)return;
	if(u == n){//得到一种答案
		ans = sd + su;
		return;
	}
	//第一种选择:将该数归为上升子序列中
	int k = 0;
	while(k < su && up[k] >= h[u])k++;
	int t = up[k];
	up[k] = h[u];
	if(k == su)dfs(u + 1,su + 1,sd);
	else dfs(u + 1, su, sd);
	up[k] = t;//回溯
	
	//第二种选择:将该数归为下降子序列中
	k = 0;
	while(k < sd && down[k] <= h[u])k++;
	t = down[k];
	down[k] = h[u];
	if(k == sd)dfs(u + 1,su,sd + 1);
	else dfs(u + 1,su,sd);
	down[k] = t;
	
}

void solve(){
	while(cin >> n && n){
		for(int i = 0; i < n; i ++)cin >> h[i];

		ans = n;

		dfs(0,0,0);

		cout << ans << endl;
	}
	
	return ;
}

int main(){
	int T = 1;

	while(T --){
		solve();
	}
	
}

posted on 2023-09-29 13:24  BkDench  阅读(38)  评论(0编辑  收藏  举报

导航