题意:

给出长度为N的数列{A_i},每次可以从最左边或者最右边取走一个数,第i次取数得到的价值是i * A_j。求价值之和最大的取数方案。

思路:

记忆化搜索:

用 DP[i][j]表示a数组取i到j的最大价值。
int a[2010];
int dp[2010][2010];
int dfs(int l,int r,int t)
{
    if(l>r)return 0;
    if(dp[l][r])returndp[l][r];
    int temp=0;
    temp=max(temp,dfs(l+1,r,t+1)+t*a[l]);
    temp=max(temp,dfs(l,r-1,t+1)+t*a[l]);
    returndp[l][r]=temp;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    printf("%d\n",dfs(1,n,1));
    return 0;
}
dp:
用 DP[i][j] 表示 a 数组左边取 i 个数右边取 j 个数所能取得的最大价值,则可得状态转移方程 
DP[i][j]=max{DP[i−1][j]+a[i]×(i+j),DP[i][j−1]+a[n−j+1]×(i+j)}。
最后结果为 max{i+j=n|DP[i][j]}.

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

数位dp Previous
51nod 1257 01分数规划 Next