【牛客oj】跳跳跳(区间dp)

2023-10-31 16:20
文章标签 dp 牛客 区间 oj 跳跳

本文主要是介绍【牛客oj】跳跳跳(区间dp),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

dd在玩跳格子游戏,具体游戏规则如下,

n个格子呈环形分布,顺时针方向分别标号为1∼n,其中1和n相邻,每个格子上都有一个正整数a[i],玩家可以选择一个点作为起点开始跳n下,第i次跳跃,玩家只可以选择当前位置左边或右边最近且尚未被跳跃过的位置进行一次跳跃,并获得i×a[p]的得分,其中ppp为第 i次跳跃的位置。

dd很鸡贼,想赢又不想动脑子,她希望你能给她规划路线以确保她的胜利

输入描述:

第一行一个数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的题目+利用开二倍数组处理环的问题

 先说一下用二倍数组处理环的问题,这是最常用的方式处理环了

a[i+n]=a[i]

(ps没有平板这图画的也太丑了,应该凑合能看懂)这n+1的位置其实就相当于2的位置,这样开到2n可以保证从1~n遍历都能是个闭合的环(说的不太清楚)


再说区间dp部分,dp[i][j]表示当前走完的点中i为左端点,j为右端点时获得的最高分,确定了i,j之后,可以确定当前走完了j-i+1步,并且当前停留在i或者j这个位置,因为每次可以向左或者向右走,当前的状态是由len-1也就是j-i这么大小的区间向左或者向右扩充一个位置得到的,那么可以得到递推方程
dp[i][j]=max(dp[i+1][j]+a[i]*(j-i+1),dp[i][j-1]+a[j]*(j-i+1))

需要注意我们在枚举时数据的范围,详细看代码,剩下就没啥问题了

 下面附上ac代码

#include <bits/stdc++.h>
using namespace std;
int n,a[4005],dp[4005][4005];
int main()
{while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++)   //开二倍数组处理环{scanf("%d",&a[i]);a[i+n]=a[i];}for(int len=1;len<=n;len++) //枚举区间长度{for(int i=1;i<=2*n-len+1;i++)   //枚举区间起点{int j=i+len-1;dp[i][j]=max(dp[i+1][j]+a[i]*(j-i+1),dp[i][j-1]+a[j]*(j-i+1));  //状态转移}}int ans=0;for(int i=1;i<=n;i++)   //寻找答案最大值{ans=max(ans,dp[i][i+n-1]);}printf("%d\n",ans);}//system("pause");return 0;
}

 

这篇关于【牛客oj】跳跳跳(区间dp)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/316612

相关文章

hdu4826(三维DP)

这是一个百度之星的资格赛第四题 题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=500 题意:从左上角的点到右上角的点,每个点只能走一遍,走的方向有三个:向上,向下,向右,求最大值。 咋一看像搜索题,先暴搜,TLE,然后剪枝,还是TLE.然后我就改方法,用DP来做,这题和普通dp相比,多个个向上

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

hdu4865(概率DP)

题意:已知前一天和今天的天气概率,某天的天气概率和叶子的潮湿程度的概率,n天叶子的湿度,求n天最有可能的天气情况。 思路:概率DP,dp[i][j]表示第i天天气为j的概率,状态转移如下:dp[i][j] = max(dp[i][j, dp[i-1][k]*table2[k][j]*table1[j][col] )  代码如下: #include <stdio.h>#include

usaco 1.1 Broken Necklace(DP)

直接上代码 接触的第一道dp ps.大概的思路就是 先从左往右用一个数组在每个点记下蓝或黑的个数 再从右到左算一遍 最后取出最大的即可 核心语句在于: 如果 str[i] = 'r'  ,   rl[i]=rl[i-1]+1, bl[i]=0 如果 str[i] = 'b' ,  bl[i]=bl[i-1]+1, rl[i]=0 如果 str[i] = 'w',  bl[i]=b

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

uva 10154 DP 叠乌龟

题意: 给你几只乌龟,每只乌龟有自身的重量和力量。 每只乌龟的力量可以承受自身体重和在其上的几只乌龟的体重和内。 问最多能叠放几只乌龟。 解析: 先将乌龟按力量从小到大排列。 然后dp的时候从前往后叠,状态转移方程: dp[i][j] = dp[i - 1][j];if (dp[i - 1][j - 1] != inf && dp[i - 1][j - 1] <= t[i]

uva 10118 dP

题意: 给4列篮子,每次从某一列开始无放回拿蜡烛放入篮子里,并且篮子最多只能放5支蜡烛,数字代表蜡烛的颜色。 当拿出当前颜色的蜡烛在篮子里存在时,猪脚可以把蜡烛带回家。 问最多拿多少只蜡烛。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cs

uva 10069 DP + 大数加法

代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <cl

uva 10029 HASH + DP

题意: 给一个字典,里面有好多单词。单词可以由增加、删除、变换,变成另一个单词,问能变换的最长单词长度。 解析: HASH+dp 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

XTU 1233 n个硬币连续m个正面个数(dp)

题面: Coins Problem Description: Duoxida buys a bottle of MaiDong from a vending machine and the machine give her n coins back. She places them in a line randomly showing head face or tail face o