题目描述
一套导弹防御系统的拦截高度要么是严格单调上升的,要么是严格单调下降的,给定\(n\)个导弹的高度,求最少需要几套导弹防御系统能够拦截所有的导弹(\(1≤n≤50\))
思路
由于\(n\)的范围只有\(50\),我们可以使用\(dfs\)来解决问题。使用\(up\)数组来表示当前每个严格单调上升的导弹防御系统的最后一个拦截的导弹高度,\(down\)数组来表示当前每个严格单调下降的导弹防御系统的最后一个拦截的导弹高度。对于每个导弹的高度,先判断是否能被已有的导弹系统拦截,如果可以,则继续搜索下一个元素,否则新建一个导弹系统。复杂度\(O(能过)\)
AC代码
#include "iostream"
#include "cstring"
#include "string"
#include "vector"
#include "cmath"
#include "algorithm"
#include "map"
#include "set"
#include "queue"
#include "stack"
#include "cassert"
#include "unordered_map"
#include "sstream"
#include "cstdio"
using namespace std;
#define fi first
#define se second
#define PB push_back
#define mst(x,a) memset(x,a,sizeof(x))
#define all(a) a.begin(),a.end()
#define rep(x,l,u) for(ll x=l;x<u;x++)
#define rrep(x,l,u) for(ll x=l;x>=u;x--)
#define sz(x) x.size()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define seteps(N) setprecision(N)
#define uni(x) sort(all(x)), x.erase(unique(all(x)), x.end())
#define lson (ind<<1)
#define rson (ind<<1|1)
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 lll;
typedef pair<int,int> PII;
typedef pair<char,char> PCC;
typedef pair<double,double> PDD;
typedef pair<ll,ll> PLL;
typedef pair<int,PII> PIII;
struct Scanner {
bool hasNext = 1;
bool hasRead = 1;
int nextInt() {
hasRead = 0;
int res = 0;
char flag = 1, ch = getchar();
while(ch != EOF && !isdigit(ch)) {
hasRead = 1;
flag = (ch == ‘-‘) ? -flag : flag;
ch = getchar();
}
while(ch != EOF && isdigit(ch)) {
hasRead = 1;
res = res * 10 + (ch - ‘0‘);
ch = getchar();
}
if(ch == EOF)
hasNext = 0;
return res * flag;
}
ll nextLL() {
hasRead = 0;
ll res = 0;
char flag = 1, ch = getchar();
while(ch != EOF && !isdigit(ch)) {
hasRead = 1;
flag = (ch == ‘-‘) ? -flag : flag;
ch = getchar();
}
while(ch != EOF && isdigit(ch)) {
hasRead = 1;
res = res * 10 + (ch - ‘0‘);
ch = getchar();
}
if(ch == EOF)
hasNext = 0;
return res * flag;
}
char nextChar() {
hasRead = 0;
char ch = getchar();
while(ch != EOF && isspace(ch)) {
hasRead = 1;
ch = getchar();
}
if(ch == EOF)
hasNext = 0;
return ch;
}
int nextString(char *str) {
hasRead = 0;
int len = 0;
char ch = getchar();
while(ch != EOF && isspace(ch)) {
hasRead = 1;
ch = getchar();
}
while(ch != EOF && !isspace(ch)) {
hasRead = 1;
str[++len] = ch;
ch = getchar();
}
str[len + 1] = 0;
if(ch == EOF)
hasNext = 0;
return len;
}
} sc;
ll rd() {
ll x = sc.nextLL();
return x;
}
void rd(int &x) {
x = sc.nextInt();
}
void rd(ll &x) {
x = sc.nextLL();
}
void rd(char &x) {
x = sc.nextChar();
}
void rd(char* x) {
sc.nextString(x);
}
template<typename T1, typename T2>
void rd(pair<T1, T2> &x) {
rd(x.first);
rd(x.second);
}
template<typename T>
void rd(T *x, int n) {
for(int i = 1; i <= n; ++i)
rd(x[i]);
}
template<typename T>
void rd(vector<T> &x,int n){
for(int i = 1; i <= n; ++i)
rd(x[i]);
}
void printInt(int x) {
if(x < 0) {
putchar(‘-‘);
x = -x;
}
if(x >= 10)
printInt(x / 10);
putchar(‘0‘ + x % 10);
}
void printLL(ll x) {
if(x < 0) {
putchar(‘-‘);
x = -x;
}
if(x >= 10)
printLL(x / 10);
putchar(‘0‘ + x % 10);
}
void pr(int x, char ch = ‘\n‘) {
printInt(x);
putchar(ch);
}
void pr(ll x, char ch = ‘\n‘) {
printLL(x);
putchar(ch);
}
//#define LOCAL
template<typename T1, typename T2>
void pr(pair<T1, T2> x, char ch = ‘\n‘) {
#ifdef LOCAL
putchar(‘<‘);
pr(x.first, ‘ ‘);
pr(x.second, ‘>‘);
putchar(ch);
return;
#endif //LOCAL
pr(x.first, ‘ ‘);
pr(x.second, ch);
}
template<typename T>
void pr(T *x, int n) {
for(int i = 1; i <= n; ++i)
pr(x[i], " \n"[i == n]);
}
template<typename T>
void pr(vector<T> &x) {
int n = x.size();
for(int i = 1; i <= n - 1; ++i)
pr(x[i], " \n"[i == n - 1]);
}
const int N=55;
const int M=1<<12;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int mod1=998244353;
const lll oone=1;
const double eps=1e-6;
const double pi=acos(-1);
int up[N],down[N],ans,n,a[N];
void dfs(int u,int top,int lower){
if(top+lower>=ans) return;
if(u==n+1) ans=top+lower;
int k=0;
while(k<top && up[k]<a[u]) k++;
int t=up[k];
up[k]=a[u];
if(k>=top) dfs(u+1,top+1,lower);
else dfs(u+1,top,lower);
up[k]=t;//回溯
k=0;
while(k<lower && down[k]>a[u]) k++;
t=down[k];
down[k]=a[u];
if(k>=lower) dfs(u+1,top,lower+1);
else dfs(u+1,top,lower);
down[k]=t;//回溯
}
void solve(){
while(scanf("%d",&n)!=EOF,n){
rd(a,n);
ans=n;
dfs(1,0,0);
pr(ans);
}
}
int main(){
//IOS;
//freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
//int t;rd(t);
//rep(i,0,t){
//printf("Case #%d: ", i+1);
solve();
//}
return 0;
}