洛谷上的题目markdown
P12175 [蓝桥杯 2025 省 Python B] 园艺
题目描述
小蓝从左到右种了 n
棵小树,第 i 棵树的高度为
hi,相邻树的间隔相同。小蓝想挪走一些树使得剩下的树等间隔分布,且从左到右高度逐渐上升(相邻两棵树高度满足右边的比左边的高),小蓝想知道最多能留下多少棵树。
输入格式
输入的第一行包含一个正整数 n。
第二行包含 n 个正整数 h1, h2, ⋯, hn,相邻整数之间使用一个空格分隔。
输出格式
输出一行包含一个整数表示答案。
输入输出样例
输入 #1
输出 #1
说明/提示
样例说明
留下第 1、3、5 棵树,它们等间隔且从左到右高度逐渐上升。
评测用例规模与约定
- 对于 30% 的评测用例,1 ≤ n ≤ 500;
- 对于 60% 的评测用例,1 ≤ n ≤ 3000;
- 对于所有评测用例,1 ≤ n ≤ 5000,0 < hi < 106。
问题概述
题目要求我们在一排树中选出尽可能多的树,满足两个条件:
- 选出的树必须是等间隔分布的
- 选出的树的高度必须严格递增
思路
可以发现类似 最长下降子序列 的问题
考虑 dp ,对于每棵树 i ,检查它前面所有的树 j ,如果树 j 的高度小于树
i 的高度,计算它们之间的间隔 diff
dp[i][d]
表示以第 i 棵树结尾,间隔为 d
的最长子序列长度
记录以树 i 结尾、间隔为 diff 的最长子序列长度
代码
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
| package 动态规划.subject.线性dp.P12175_蓝桥杯2025_省_PythonB_园艺;
import java.util.Scanner;
public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] tree = new int[n]; for (int i = 0; i < n; i++) { tree[i] = sc.nextInt(); }
int[][] dp = new int[n][n]; int max = 1;
for (int i = 0; i < n; i++) { dp[i][0] = 1; }
for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { if (tree[j] < tree[i]) { int diff = i - j; int prev = dp[j][diff]; if (prev == 0) { prev = 1; } if (dp[i][diff] < prev + 1) { dp[i][diff] = prev + 1; if (dp[i][diff] > max) { max = dp[i][diff]; } } } } }
System.out.println(max); sc.close(); } }
|
因为是 python 组的题目,所以这里放一下python的代码
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
| def main(): import sys input = sys.stdin.read data = input().split() n = int(data[0]) tree = list(map(int, data[1:n+1])) dp = [[0] * n for _ in range(n)] max_len = 1 for i in range(n): dp[i][0] = 1 for i in range(n): for j in range(i): if tree[j] < tree[i]: diff = i - j prev = dp[j][diff] if prev == 0: prev = 1 if dp[i][diff] < prev + 1: dp[i][diff] = prev + 1 if dp[i][diff] > max_len: max_len = dp[i][diff] print(max_len)
if __name__ == "__main__": main()
|