拦截导弹
时间限制:3000 ms | 内存限制:65535 KB
难度:3
某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于等于前一发的高度。某天,雷达捕捉到敌国导弹来袭。由于该系统还在试用阶段,所以只用一套系统,因此有可能不能拦截所有的导弹。
接下来一行输入这组测试数据共有多少个导弹m(1<=m<=20)
接下来行输入导弹依次飞来的高度,所有高度值均是大于0的正整数。
2 8 389 207 155 300 299 170 158 65 3 88 34 65
6 2
思路:
最长下降子序列。数据比较小,直接 dp O(n ^ 2)做法就好了。考试复习期间练练手,刷刷水题。
AC:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int num[25], dp[25]; int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%d", &num[i]); dp[i] = 1; } int Max = 1; for (int i = 2; i <= n; ++i) { for (int j = 1; j < i; ++j) { if (num[i] < num[j] && dp[j] + 1 > dp[i]) dp[i] = dp[j] + 1; } Max = max(Max, dp[i]); } printf("%d\n", Max); } return 0; }
相关推荐
\[a_i > a_j > a_k > \cdots > a_m\] 且 \(i > j > k > \cdots > m\)(最长下降子序列)。 **解决思路:** 问题的关键在于找到最长非降子序列或最长下降子序列。我们可以通过动态规划的方法来解决这个问题。 **...
第一部分与最长下降子序列问题类似,我们可以设计状态`opt[i]`表示拦截到第`i`个导弹时,最多可以拦截到的导弹数量。状态转移方程同样为`opt[i]=max(opt[j])+1`,其中`h[i]>=h[j]`,`0=,`h[i]`表示第`i`个导弹的...
类似的动态规划问题还包括最长下降子序列、最长上升子串和最长公共子串等。这些问题都可以通过动态规划的思想,利用子问题的最优解来构建原问题的最优解。 最后,像石子合并这样的区域动归问题,我们可以用动态规划...
我们分别找出以每个元素为结尾的最长上升子序列和以每个元素为起点的最长下降子序列,它们的和即为答案。状态 `dp1[i]` 和 `dp2[i]` 分别表示到位置 `i` 的最长上升子序列和下降子序列。状态转移方程分别为 `dp1[i] ...
例如,最长不下降子序列问题中,状态(i)表示以第 i 个元素结尾的最长不下降序列的长度。通过使用单调辅助数组和二分查找,可以将时间复杂度优化至O(nlogn)。类似的应用还包括拦截导弹、Beautiful People和Segment...
这些例题涵盖了不同的动态规划类型,包括下降/非降子序列、背包问题、最长公共子序列、石子合并问题等。例如,拦截导弹问题可以通过动态规划确定每个时刻的最优拦截策略,背包问题则需要找出如何在容量限制下选取...
1. **最长不下降子序列** - **状态定义**:\( dp[i] \) 表示以第 i 个元素结尾的最长非降子序列的长度。 - **转移方程**:\( dp[i] = max(dp[j] + 1) \) 其中 \( j ) 且 \( nums[j] \leq nums[i] \)。 - **优化**...