🎈 作者:Linux猿
🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊!
🎈 关注专栏: 数据结构和算法成神路【精讲】优质好文持续更新中……🚀🚀🚀
🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬
目录
一、题目描述
1.1 输入描述
1.2 输出描述
1.3 测试样例
1.3.1 示例 1
二、解题思路
三、代码实现
四、时间复杂度
一、题目描述
给定一个长度为 n 的整型数组,表示一个选手在 n 轮内可选择的牌面分数。选手基于规则选牌,请计算所有轮结束后其可以获得的最高总分数。选择规则如下:
在每轮里选手可以选择获取该轮牌面,则就在其总分数加上该轮牌面分数,作为新的总分数。
选手也可以不选择本轮牌面直接跳到下一轮,但此时需要将当前总分数还原为 3 轮前的总分数,若当前轮次小于等于 3 (即在第1、2、3轮选择跳过),则总分数置为 0。
选手的初始总分数为 0,且必须依次参加每一轮。
1.1 输入描述
第一行为一个小写逗号分隔的分值字符串,表示这 n 轮的牌面分数, 1 <= n <= 20。
分数值为整数,范围是 -100 到 100。
不考虑格式问题。
1.2 输出描述
所有轮结束后选手能够获得的最高总分数。
1.3 测试样例
1.3.1 示例 1
输入
1,-5,-6,4,3,6,-2
输出
11
说明:
这里总共 7 轮牌面。
第一轮选择该轮牌面,总分数为 1。
第二轮不选择该轮牌面,总分数还原为 0。
第三轮不选择该轮牌面,总分数还原为 0。
第四轮选择该轮牌面,总分数为 4。
第五轮选择该轮牌面,总分数为 7。
第六轮选择该轮牌面,总分数为 13。
第七轮如果不选择该轮牌面,则总分还原到 3 轮前的分数,即第四轮的总分数 4;如果选择牌面,总分数为 11。所以选择该轮牌面。
因此,最终的最高总分数为 11。
二、解题思路
本题是一道简单的动态规划题,假设 dp[i] 表示选择到第 i 个牌面最高分数,g[ i ] 表示第 i 个牌面的分数,i >= 0,动态方程如下所示:
(1) dp[ i ] = max(g[ i ], 0) i <= 2,(i >= 0)
(2) dp[ i ] = max(dp[ i - 3], dp[ i - 1 ] + g[ i ]) i >= 3
三、代码实现
代码实现如下所示。
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
string str;
while (getline(cin, str)) {
vector<int>g;
stringstream stream(str);
while (getline(stream, str, ',')) {
g.push_back(atoi(str.c_str()));
}
const int n = g.size();
int dp[n];
for (int i = 0; i < n; i++) {
if (i <= 2) {
dp[i] = max(0, g[i]);
} else {
dp[i] = max(dp[i - 3], dp[i - 1] + g[i]);
}
}
cout<<dp[n - 1]<<endl;
}
return 0;
}
四、时间复杂度
时间复杂度:O(n)。
其中,n 表示牌面的个数,在上述代码中,首先需要解析输入的字符串,然后遍历一遍牌面的分数,所以时间复杂度为O(n)。
🎈 感觉有帮助记得「一键三连」支持下哦!有问题可在评论区留言💬,感谢大家的一路支持!🤞猿哥将持续输出「优质文章」回馈大家!🤞🌹🌹🌹🌹🌹🌹🤞