导弹拦截(线性DP)

导弹拦截(Acwing)


题目大意:

导弹拦截系统:第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。

计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统


题目分析:

题目分析:

 第一问很明显就是求最长下降子序列

 第二问实则再问最少有多少个下降子序列  最少有多少个下降子序列就是求最长不下降子序列的长度 因为这个最长不下降子序列的元素不可能在同一个下降序列中


AC代码:

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
int p[N], d[N];

int ULIS(int n)//最长非下降子序类
{
	int len = 1;
	d[1] = p[1];
	for (int i = 2; i <= n; ++i)
	{
		if (p[i] > d[len]) d[++len] = p[i];
		else
		{
			int j = lower_bound(d + 1, d + 1 + len, p[i]) - d;
			d[j] = p[i];
		}
	}
	return len;
}

int DLIS(int n)//最长下降子序列
{
	int res = 0;

	for (int i = n; i >= 1; --i)
	{
		for (int j = n + 1; j > i; --j)
		{
			if (p[i] >= p[j]) d[i] = max(d[i], d[j] + 1);
		}
		res = max(res, d[i]);
	}
	return res;
}



int main(void)
{
	int n = 0;
	int x;
	while (cin >> x) p[++n] = x;
	cout << DLIS(n) << endl;

	cout << ULIS(n) << endl;
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值