1061 跳跳跳 区间DP

链接:https://ac.nowcoder.com/acm/contest/24213/1061
来源:牛客网

题目描述

dddddd在玩跳格子游戏,具体游戏规则如下,
nnn个格子呈环形分布,顺时针方向分别标号为1∼n1\sim n1n,其中111和nnn相邻,每个格子上都有一个正整数a[i]a[i]a[i],玩家可以选择一个点作为起点开始跳nnn下,第iii次跳跃,玩家只可以选择当前位置左边或右边最近且尚未被跳跃过的位置进行一次跳跃,并获得i×a[p]i\times a[p]i×a[p]的得分,其中ppp为第 iii次跳跃的位置。
dddddd很鸡贼,想赢又不想动脑子,她希望你能给她规划路线以确保她的胜利

输入描述:

第一行一个数n(1≤n≤2000)
接下来一行n个数,表示a[i](1≤a[i]≤2000)

输出描述:

一个数,表示dd可能获得的最高分
示例1

输入

复制
3
1 1 1

输出

复制
6

说明

可能方案
1->2->3
1->3->2
2->1->3
2->3->1
3->1->2
3->2->1
(以上数字表示格子标号)
答案均为 1*1+2*1+3*1=6
最优方案不唯一,最优答案唯一
示例2

输入

复制
3
1 2 3

输出

复制
14

说明

方案:1->2->3(数字对应格子标号)
答案:1*1+2*2+3*3=14
最优方案唯一

分析

区间DP

//-------------------------代码----------------------------

//#define int ll
const int N = 5000;
int n,m;
int a[N];
int dp[N][N];
void solve()
{
cin>>n;
fo(i,1,n) {
cin>>a[i];
dp[i][i] = dp[i+n][i+n] = a[i+n] = a[i];
}
fo(k,2,n) {
for(int i = 1,j = k;j<= 2 * n;i ++ ,j ++ ) {
dp[i][j] = max(dp[i+1][j] + a[i] * k,dp[i][j-1] + a[j] * k);
}
}
int ans = 0;
fo(i,1,n) ans = max(ans,dp[i][n+i-1]);
cout<<ans<<endl;
}

signed main(){
clapping();TLE;

// int t;cin>>t;while(t -- )
solve();
// {solve(); }
return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-07-23 19:52  er007  阅读(60)  评论(0编辑  收藏  举报