NC227595 跳跳跳
题目
题目描述
dd在玩跳格子游戏,具体游戏规则如下,
个格子呈环形分布,顺时针方向分别标号为 ,其中 和 相邻,每个格子上都有一个正整数 ,玩家可以选择一个点作为起点开始跳 下,第 次跳跃,玩家只可以选择当前位置左边或右边最近且尚未被跳跃过的位置进行一次跳跃,并获得 的得分,其中 为第 次跳跃的位置。
dd很鸡贼,想赢又不想动脑子,她希望你能给她规划路线以确保她的胜利
输入描述
第一行一个数
接下来一行 个数,表示
输出描述
一个数,表示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。
题意就是每次选区已扩展区间的左右侧最近的一个点,起点随意,因此是个环状区间dp可以解决的问题。
开两倍端点,处理环状。转移方程为:
表示为选择 的左端点或右端点作为第 个选择的对象。
类似问题有POJ2287的田忌赛马,也是选择区间左右端点的区间dp,但区别在于这道题是起点确定,田忌赛马是终点确定,选择的是第 个。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; int a[2007 << 1]; ll dp[2007 << 1][2007 << 1]; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; cin >> n; for (int i = 1;i <= n;i++) { cin >> a[i]; a[i + n] = a[i]; } for (int i = 1;i <= 2 * n;i++) dp[i][i] = a[i]; for (int l = 2;l <= n;l++) { for (int i = 1, j = l;j <= 2 * n;i++, j++) { dp[i][j] = max(dp[i + 1][j] + l * a[i], dp[i][j - 1] + l * a[j]); } } ll ans = 0; for (int i = 1;i <= n;i++) ans = max(ans, dp[i][i + n - 1]); cout << ans << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16589890.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧