题意:
给出长度为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 协议 ,转载请注明出处!