TCS 模拟生活 2019 第 2 轮问题:跳跃游戏
TCS MockVita 2019 Round 2 Question: Hop Game
我正在尝试解决TCS MockVita 2019第2轮中提出的问题:
问题描述
高斯学校的数学老师Felix Kline博士介绍了以下游戏来教他的学生解决问题。他将一系列"跳石"(纸片)排成一条线,每块石头上都标有点(正数)。
学生从一端开始,跳到另一端。一个人可以踩到一块石头,将石头上的数字添加到他们的累积分数中,或者跳过一块石头,落在下一块石头上。在这种情况下,他们得到的分数是他们降落的石头上标记的两倍,但没有得到他们跳过的石头上标记的分数。
在旅程中最多一次,学生被允许(如果他们选择)进行"双跳"——也就是说,他们跳过两块连续的石头——在那里他们将获得他们落在的石头上的三倍的点,但不是他们跳过的石头的点。
老师希望他的学生做一些思考,并提出一个计划,以获得尽可能高的分数。给定石头序列上的数字,编写一个程序来确定可能的最高分数。
约束
序列中的宝石数量<30
输入格式
第一行包含 N,整数的个数(这是一个正整数)
下一行包含用逗号分隔的 N 个点(每个点都是正整数)。这些是石头上按石头放置顺序排列的点。
输出
一个整数表示最高分
测试用例
解释
例 1
输入
3
4,2,3
输出
10
解释
有 3 块石头 (N=3),点(按布局顺序)分别为 4、2 和 3。
如果我们踩到第一块石头并跳过第二块石头得到 4 + 2 x 3 = 10。双跳到第三块石头只会得到 9。因此结果为 10,并且不使用双跳
例 2
输入
6
4,5,6,7,4,5
输出
35
解释
N=6,并给出点的顺序。获得 35 的一种方法是从两次跳到石头 3 (3 x 6=18) 开始,转到石头 4 (7) 并跳到石头 6(10 分),总共 35 分。双跳只用了一次,结果是35。
我发现这是一个动态编程问题,但我不知道我做错了什么,因为我的解决方案无法通过所有测试用例。我的代码通过了我创建的所有测试。
unordered_map<int, int> lookup;
int res(int *arr, int n, int i){
if(i == n-1){
return 0;
}
if(i == n-2){
return arr[i+1];
}
if(lookup.find(i) != lookup.end())
return lookup[i];
int maxScore = 0;
if(i< n-3 && flag == false){
flag = true;
maxScore = max(maxScore, 3 * (arr[i+3]) + res(arr, n, i+3));
flag = false;
}
maxScore = max(maxScore, (arr[i+1] + res(arr,n,i+1)));
lookup[i] = max(maxScore, 2 * (arr[i+2]) + res(arr, n, i+2));
return lookup[i];
}
cout << res(arr, n, 0) + arr[0]; // It is inside the main()
我希望你能在我的代码中找到错误并提供正确的解决方案,以及任何未能通过此解决方案的测试用例。谢谢:)
你不需要任何地图。您需要记住的是最后几个最大值。你每个动作有两个选项(除了两个第一个),以双跳结束或不做它。如果你不想做一个DJ,那么你最好的快乐是最后一块石头+电流和最后一块石头+2 *当前max(no_dj[2] + arr[i], no_dj[1] + 2 * arr[i])
之前的最大石头。
另一方面,如果你想制作 dj,那么你有三个选择,要么在之前的 djdj[2] + arr[i]
后跳一块石头,要么在一些 djdj[1] + 2 * arr[i]
后跳过最后一块石头,或者在当前的移动no_dj[0] + 3 * arr[i]
中做双跳。
int res(int *arr, int n){
int no_dj[3]{ 0, 0, arr[0]};
int dj[3]{ 0, 0, 0};
for(int i = 1; i < n; i++){
int best_nodj = max(no_dj[1] + 2 * arr[i], no_dj[2] + arr[i]);
int best_dj = 0;
if(i > 1) best_dj = max(max(dj[1] + 2 * arr[i], dj[2] + arr[i]), no_dj[0] + 3 * arr[i]);
no_dj[0] = no_dj[1];
no_dj[1] = no_dj[2];
no_dj[2] = best_nodj;
dj[0] = dj[1];
dj[1] = dj[2];
dj[2] = best_dj;
}
return max(no_dj[2], dj[2]);
}
您所要记住的只是两个由三个元素组成的数组。双跳后的最后三个最大值和没有双跳后的最后三个最大值。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- TCS 模拟生活 2019 第 2 轮问题:跳跃游戏
- 跳跃游戏中嵌套的循环问题
- 玩家跳跃的问题
- 提升灵气问题与字符串和跳跃