PAT甲級1007 Maximum Subsequence Sum (25 分)題解

在這裏插入圖片描述
\quad這是最大子序列和問題,是一個典型的動態規劃題目,我在博客中對幾個常見的動態規劃算法進行了分析。設輸入的數保存在數組a[max]中,那麼轉移方程爲dp[i]=max(dp[i-1]+a[i],a[i])。最大子序列和即爲dp數組的最大值res,我們記錄下zp數組第一次出現最大值的位置last,從last往前將a[i]數組的值加起來,直到值爲res爲止,此時的位置就是最大子序列的起始位置first。需注意題目規定當輸入的數全爲負數時輸出0和首位、末尾的數,這點需要提前特判。

#include <stdio.h>
#include <algorithm>
using namespace std;

const int maxn = 1e4+10;
int a[maxn], dp[maxn];

int main(int argc, char const *argv[])
{
	int K; scanf("%d", &K);
	for(int i = 1; i <= K; i++) scanf("%d", &a[i]);
	// 特判:若輸入的數全部小於0,則輸出0和首位、末尾的數
	bool flag = true;
	for (int i = 1; i <= K; ++i){
		if(a[i]>=0) flag=false;
	}
	if(flag){
		printf("%d %d %d\n", 0, a[1], a[K]);
		return 0;
	}
	// 開始dp
	dp[1] = a[1];
	int res = dp[1];
	for(int i = 2; i <= K; i++){
		dp[i] = max(dp[i-1]+a[i], a[i]);
		res = max(res, dp[i]);
	}
	int first, last;  // 記錄首位和末位
	for(int i = 1; i <= K; i++){
		if(dp[i]==res) {
			last=i;
			break;
		}
	}
	int temp = 0;
	for(int i = last; i >= 1; i--){
		temp += a[i];
		if(temp==res) {
			first=i;
			break;
		}
	}
	printf("%d %d %d\n", res, a[first], a[last]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章