洛谷-1020-导弹拦截满分题解-python-代码解析全复制

题目描述

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度,计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入格式

一行,若干个整数,中间由空格隔开。

输出格式

两行,每行一个整数,第一个数字表示这套系统最多能拦截多少导弹,第二个数字表示如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :1020导弹拦截.py
# @Time      :2022/11/19 20:31
# @Author    :YKW
'''第一问,最长不上升子序列
   第二问,最长上升子序列
'''


def lisfun1(nums):
    if not nums:
        return 0
    n = len(nums)
    #  dp[i]表示以第i个元素结尾的最长递增子序列长度,初始值为1
    dp = [1 for _ in range(n)]
    # 遍历每一个元素,求以每一个元素为结尾的最长递增子序列长度
    for i in range(n):
        for j in range(i):
            # 遍历i前面的所有元素,如果nums[j] < nums[i],则求一次dp[i] = max(dp[i],dp[j] + 1)
            if nums[i] > nums[j]:
                dp[i] = max(dp[i], dp[j] + 1)
    return max(dp)


def lisfun2(arr):
    n = len(arr)
    m = [0] * n
    for x in range(n - 2, -1, -1):
        for y in range(n - 1, x, -1):
            if arr[x] < arr[y] and m[x] <= m[y]:
                m[x] += 1
        max_value = max(m)
        result = []
        for i in range(n):
            if m[i] == max_value:
                result.append(arr[i])
                max_value -= 1
    return result

lst = list(map(int, input().split()))
print(lisfun1(lst))
print(lisfun2(lst))

'''
def lisfun1(nums):
    if not nums:
        return 0
    n = len(nums)
    #  dp[i]表示以第i个元素结尾的最长递增子序列长度,初始值为1
    dp = [1 for _ in range(n)]
    dp2=[1 for _ in range(n)]
    # 遍历每一个元素,求以每一个元素为结尾的最长递增子序列长度
    for i in range(n):
        for j in range(i):
            # 遍历i前面的所有元素,如果nums[j] < nums[i],则求一次dp[i] = max(dp[i],dp[j] + 1)
            if nums[i] > nums[j]:
                dp[i] = max(dp[i], dp[j] + 1)
            else:
                dp2[i]=max(dp2[i], dp2[j]+1)
    return max(dp2),max(dp)

lst = list(map(int, input().split()))
print(lisfun1(lst)[0],lisfun1(lst)[1],sep='\n')
'''
'''
lst = list(map(int, input().split()))
ans = [1 for i in range(len(lst))]
ans2 = [1 for i in range(len(lst))]
ddp = [1 for i in range(len(lst))]
def dp(i):
    maxx = ddp[i]
    in_maxx = i
    for j in range(i + 1, len(lst)):
        if maxx < dp[j]:
            in_maxx = j
            maxx = dp[j]
    if in_maxx != i:
        ddp[i] = maxx
    return ddp[i]


def fun1(lst):  # 70%的点,其他TLE
    for i in range(len(lst) - 1, -1, -1):
        in_max = i
        in_max2 = i
        for j in range(i + 1, len(lst)):  # j在i后面
            if lst[j] <= lst[i] and ans[in_max] < ans[j] + 1:
                in_max = j
            if lst[j] > lst[i] and ans2[in_max2] < ans2[j] + 1:
                in_max2 = j
        if in_max != i:
            ans[i] = ans[in_max] + 1
        if in_max2 != i:
            ans2[i] = ans2[in_max2] + 1
    print(max(ans))
    print(max(ans2))'''

# fun1(lst)

# def fun1(lst):
#     for i in range(len(lst)-1,-1,-1):
#         in_max=i
#         for j in range(i+1,len(lst)): # j在i后面
#             if lst[j]<=lst[i] and ans[in_max]<ans[j]+1:
#                 in_max=j
#         if in_max!=i:
#             ans[i]=ans[in_max]+1
#     print(max(ans))

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值