1010. 拦截导弹

摘要
Title: 1010. 拦截导弹
Tag: dp、最长上升子序列
Memory Limit: 64 MB
Time Limit: 1000 ms

Powered by:NEFU AB-IN

Link

1010. 拦截导弹

  • 题意

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。

但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。

某天,雷达捕捉到敌国的导弹来袭。

由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数,导弹数不超过1000),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

  • 思路

第一问,就是问最长不上升子序列为多长
第二问转变一下思想,比如例子 5 4 6 7 3 2 1,第一问的结果为 5 4 3 2 1,如果再要一个序列就是 6,再要就是7,可以发现就和最大值有关,所以反着求一个最长下降子序列即可(不是最长不下降,因为如果为 ``5 4 7 7 3 2 1,在第二轮就剩下7 7`,如果按第一问来做,一个7的导弹系统就可以了)

  • 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# import
from sys import setrecursionlimit, stdin, stdout, exit
from collections import Counter, deque, defaultdict
from heapq import heapify, heappop, heappush, nlargest, nsmallest
from bisect import bisect_left, bisect_right
from datetime import datetime, timedelta
from string import ascii_lowercase, ascii_uppercase
from math import log, gcd, sqrt, fabs, ceil, floor
from types import GeneratorType
from typing import TypeVar, List, Dict, Any, Callable, Union
T = TypeVar('T')


# Data structure
class SA:
def __init__(self, x, y):
self.x = x
self.y = y

def __lt__(self, other):
return self.x < other.x


# Constants
N = int(2e5 + 10) # If using AR, modify accordingly
M = int(20) # If using AR, modify accordingly
INF = int(2e9)
E = int(100)

# Set recursion limit
setrecursionlimit(INF)

# Read
input = lambda: stdin.readline().rstrip("\r\n") # Remove when Mutiple data
read = lambda: map(int, input().split())
read_list = lambda: list(map(int, input().split()))


# Func
class std:

# Recursion
@staticmethod
def bootstrap(f, stack=None):
if stack is None:
stack = []

def wrappedfunc(*args, **kwargs):
if stack:
return f(*args, **kwargs)
else:
to = f(*args, **kwargs)
while True:
if isinstance(to, GeneratorType):
stack.append(to)
to = next(to)
else:
stack.pop()
if not stack:
break
to = stack[-1].send(to)
return to

return wrappedfunc

letter_to_num = staticmethod(lambda x: ord(x.upper()) - 65) # A -> 0
num_to_letter = staticmethod(lambda x: ascii_uppercase[x]) # 0 -> A
array = staticmethod(lambda x=0, size=N: [x] * size)
array2d = staticmethod(
lambda x=0, rows=N, cols=M: [std.array(x, cols) for _ in range(rows)])
max = staticmethod(lambda a, b: a if a > b else b)
min = staticmethod(lambda a, b: a if a < b else b)
filter = staticmethod(lambda func, iterable: list(filter(func, iterable)))
@staticmethod
def find(container: Union[List[T], str], value: T) -> int:
"""Returns the index of value in container or -1 if value is not found."""
if isinstance(container, list):
try:
return container.index(value)
except ValueError:
return -1
elif isinstance(container, str):
return container.find(value)

# —————————————————————Division line ——————————————————————
nums = read_list()
n = len(nums)
dp = std.array(1, n)

res = 0

for i in range(n):
for j in range(i):
if nums[i] <= nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
res = max(res, dp[i])
print(res)


res = 0
nums = nums[::-1]
dp = std.array(1, n)
for i in range(n):
for j in range(i):
if nums[i] < nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
res = max(res, dp[i])
print(res)

使用搜索:谷歌必应百度