解题思路:
题意就告诉你要求你经过的点是上升序,让你求最大和;
令dp[i]表示以i为结尾的最大上升字段和;
转移方程是:dp[i] = max(dp[j] + ac[j], dp[i]) 如果ac[j] < ac[i];
有一种转移方式是错误的,:
if(ac[i] > ac[j]) {
dp[i] = max(dp[j] + ac[i], dp[j]);
}
else {
dp[i] = max(dp[i], dp[j]);
}
这种方式的意思是dp[i] 表示未必站在i位置时经过i的最大值,这种转移方式是错误的,并不能保证dp[i]在加上下一位的时候,dp[i]的最后一位ac[i]是小于ac[i +1]。
AC代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <random>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1010;
const int inf = 0x3f3f3f3f;
ll ac[maxn];
ll dp[maxn];
int main() {
int n;
while(cin >> n && n) {
for (int i = 1; i <= n; i++) {
scanf("%lld", &ac[i]);
dp[i] = ac[i];
}
ll max_ = -inf;
for (int i = 1; i <= n; i ++) {
for (int j = 1; j < i; j++) {
if(ac[i] > ac[j]) {
dp[i] = max(dp[j] + ac[i], dp[i]);
}
}
max_ = max(max_, dp[i]);
}
cout << max_ << endl;
}
}