最大连续子序列(浙江大学复试题)
动态规划问题
在最大连续子序列的基础问题上,要求输出子序列的第一个和最后一个数据,且对子序列全部为负数时需进行单独的处理
#include<vector>
using namespace std;
int main() {
int n;
while (cin >> n) {
if (n == 0)
return 0;
vector<int> nums(n), dp(n);
//1. input data
bool ifAllMinus = true;
for (int i = 0; i < n; i++) {
cin >> nums[i];
if (nums[i] >= 0)
ifAllMinus = false;
}
//序列中全为负数的处理补丁
if (ifAllMinus) {
cout << 0 << " " << nums[0] << " " << nums[n-1] << endl;
continue;
}
//序列中只有一个数字时的处理补丁
if (n == 1) {
cout << nums[0] << " " << nums[0] << " " << nums[0] << endl;
continue;
}
//2. 计算最大连续子序列
int ans_sum = -10e6;
int ans_left = 0;
int ans_right = n;
for (int i = 0; i < n; i++) {
if (i == 0)
dp[0] = nums[0];
else {
dp[i] = max(dp[i - 1] + nums[i], nums[i]);
if (dp[i] > ans_sum) {
ans_sum = dp[i];
ans_right = i;//最大子序列的右侧节点
//计算出最大子序列的左侧节点
int p = i;
int p_sum = ans_sum;
for (int j = i; j > 0; j--) {
p_sum = p_sum - nums[j];
if (p_sum == 0) {
ans_left = p;
break;
}
p--;
}
}
}
}
//3. output data
cout << ans_sum << " " << nums[ans_left] << " " << nums[ans_right] << endl;
}
return 0;
}