最大上升子序列和 (抄答案十分钟,debug两小时)【编程风格】

原题地址
在这里插入图片描述
在这里插入图片描述
⭐ DP + 离散化 + 树状数组

🤬 切记:全局变量和局部变量同名的时候,在局部内局部变量优先! 【TMD】
在这里插入图片描述

import java.io.*;
import java.util.*;

public class Main
{
	static int N = 100010, n;
	static long[] tr = new long[N];// 树状数组维护区间最大值
	static long[] f = new long[N];// DP数组
	static int[] h = new int[N];// 离散化数组

	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

	static int lowbit(int x)
	{
		return x & -x;
	}

	static long query(int x)
	{
		long res = 0;
		for (int i = x; i > 0; i -= lowbit(i))
		{
			res = Math.max(res, tr[i]);
		}

		return res;
	}

	static void add(int x, long c)
	{
		for (int i = x; i <= n; i += lowbit(i))
		{
			tr[i] = Math.max(tr[i], c);
		}
	}

	public static void main(String[] args) throws IOException
	{
		// 错误示范
//		int n = Integer.parseInt(in.readLine());  // 变量重定义导致全局变量没有get到值,我是垃圾
		n = Integer.parseInt(in.readLine());
		int[] w = new int[n];
		String[] ss = in.readLine().split(" ");
//		输入原序列
		for (int i = 0; i < n; i++)
			w[i] = Integer.parseInt(ss[i]);

// 		for (int i = 0; i < n; i++)
// 			System.out.println(w[i]);

//      输入测试 
//		Scanner sc = new Scanner(System.in);
//		n = sc.nextInt();
//		int[] w = new int[n];
//		for (int i = 0; i < n; i++)
//		{
//			w[i] = sc.nextInt();
//		}

//		离散化
		solve(w);
// 		System.out.print("w[] = ");
// 		for (int i = 0; i < n; i++)
// 			System.out.print(w[i] + " ");
// 		System.out.println();

//		求解
		long res = 0;
		for (int i = 0; i < n; i++)
		{
			// 离散化后的下标
			int k = h[i];
			f[i] = query(k - 1) + w[i];
//			System.out.println(i + " " + k + " " + query(k - 1) + " " + f[i]);  //输出调试
			res = Math.max(res, f[i]);
			add(k, f[i]);//更新符合题目条件的前缀和
		}

		System.out.println(res);
	}

	private static void solve(int[] w)
	{
		SortedSet<Integer> set = new TreeSet<>();
		for (int a : w)
		{
			set.add(a);
		}
		int[] c = new int[set.size()];
		int cnt = 0;
		for (int s : set)
		{
			c[cnt++] = s;
		}

		for (int i = 0; i < w.length; i++)
		{
			h[i] = Arrays.binarySearch(c, w[i]) + 1;
		}
	}
}

posted @ 2023-03-24 20:07  兑生  阅读(19)  评论(0)    收藏  举报  来源
Live2D