题目链接
这题是经典的动态规划题:最大连续子序列和,这题多出来的就是如何存储这个最大子序列和的起始点和终点;
这题可以首先写出最基础的最大连续子序列和,然后在此基础上思考如何通过一定的数据结构保存最大连续子序列和的起点和终点;
需要注意的是:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) throws IOException { StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); sc.nextToken(); int n = (int)sc.nval + 1; int[] d = new int[n]; for(int i=1; i<n; ++i){ sc.nextToken(); d[i] = (int)sc.nval; } int[] dp = new int[n]; // 保存连续和 dp[0] = 0; int max = Integer.MIN_VALUE; int start = 1, end = 1; int[] num = new int[n]; // 保存当前连续和的起始点,如num[4] = 1表示当前的最大和是第1-4位数的和 for(int i=1; i<n; ++i){ if(dp[i-1] > 0){ dp[i] = dp[i-1] + d[i]; num[i] = num[i-1]; }else{ dp[i] = d[i]; num[i] = i; } if(dp[i] > max){ max = dp[i]; start = num[i]; end = i; } } if(max < 0){ System.out.println(0 + " " + d[1] + " " + d[n-1]); }else{ System.out.println(max + " " + d[start] + " " + d[end]); } } }
如果想看最大连续序列和,只要将上述代码的num数组全部去掉即可;
可以在解法一的基础上进行空间优化;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) throws IOException { StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); sc.nextToken(); int n = (int)sc.nval + 1; int[] d = new int[n]; for(int i=1; i<n; ++i){ sc.nextToken(); d[i] = (int)sc.nval; } int max = -1; int start = 1, end = 1; int temp = 0, tempIndex = 1; for(int i=1; i<n; ++i){ temp += d[i]; if(temp < 0){ temp = 0; tempIndex = i + 1; }else if(temp > max){ max = temp; start = tempIndex; end = i; } } if(max < 0){ System.out.println(0 + " " + d[1] + " " + d[n-1]); }else{ System.out.println(max + " " + d[start] + " " + d[end]); } } }