Think:
1知识点:区间dp
2题意:给定一个长度为n的序列,从1开始取n次,每次可以选取第一个结点或者最后一个结点,每次获取的价值为当前次数乘以选取的结点数值,询问经过n次选取后所获得的总价值最大值
3思路:逆向思考,从最后一个获取的结点开始从里向外更新,逐渐恢复原始序列
以下为Accepted代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2014;
int a[N], dp[N][N];
int main(){
int n, i, j, k;
while(~scanf("%d", &n)){
for(i = 1; i <= n; i++){
scanf("%d", &a[i]);
dp[i][i] = a[i]*n;/*初始化假设以当前结点作为最后获取结点进而从里往外试探最优解*/
}
for(k = 1; k < n; k++){/*枚举区间长度*/
for(i = 1; i+k <= n; i++){
j = i+k;/*区间右端点*/
dp[i][j] = max(dp[i+1][j]+a[i]*(n-k), dp[i][j-1]+a[j]*(n-k));/*思想:从里往外试探最优解*/
}
}
printf("%d\n", dp[1][n]);
}
return 0;
}