LeetCode周赛#203 题解
1561. 你可以获得的最大硬币数目 #贪心
题目链接
题意
有 3n 堆数目不一的硬币,你和你的朋友们打算按以下方式分硬币:
- 每一轮中,你将会选出 任意 3 堆硬币(不一定连续)。
- Alice 将会取走硬币数量最多的那一堆。
- 你将会取走硬币数量第二多的那一堆。
- Bob 将会取走最后一堆。
重复这个过程,直到没有更多硬币。
给你一个整数数组piles ,piles[i] 是第 i 堆中硬币的数目。现要你求出可获得的最大硬币数目。
分析
毫无疑问,需要先将硬币堆降序排序。既然每一轮我只能拿当前三堆中的第二大,为了让我的硬币数更多,应先让Bob从后面堆中取极小硬币堆,我与Alice在前面取极大硬币堆。

class Solution {
public:
int maxCoins(vector<int>& piles) {
sort(piles.begin(), piles.end());
reverse(piles.begin(), piles.end());
int cnt = 0, sum = 0;
int L = 0, R = piles.size() - 1;
for (int L = 1; L < piles.size() && L < R; L += 2, R--){
sum += piles[L];
}
return sum;
}
};
1562. 查找大小为M的最新分组 #二分思想 #STL #逆向思维
题目链接
题意
给定一数组 arr ,该数组表示一个从 1 到 n 的数字排列。有一个长度为 n 的二进制字符串,该字符串上的所有位最初都设置为 0 。在从 1 到 n 的每个步骤 i 中(从 1 开始索引),二进制字符串上位于位置 arr[i] 的位将会设为 1 。
给定整数 m ,现要找出二进制字符串上存在长度为 m的一组 "1" 的最后步骤。一组 "1" 是一个连续的、由 1 组成的子串,且左右两边不再有可以延伸的 1 。如果不存在这样的步骤,请返回 -1 。
样例

分析
\(O(n)\)的解法可戳此,此处提供易写的版本,同时学习set的 用法,不过复杂度约为\(O(nlogn)\)。
既然它要我们找出“最后”的步骤,可以尝试逆向思考,即从全为"111…11"串转化为"110010..."串,一旦串中出现长度恰为m的"1"子串即可返回。
如何在每一次操作中计算每个"1"串的长度?我们可以利用set的自动排序以及它自带的二分函数,将每一次置0的位置插入到set中,插入时需要通过二分(尽量使用set自带的二分函数,因为通用的二分函数不支持随机访问的容器,使得复杂度达到\(O(n)\)),主要是为了找到它的新插入位置附近的迭代器,通过对迭代器代表的位置做差即可得到特定"1"串的长度。
class Solution {
private:
int sum[505] = {0};
set<int> vis;
public:
int findLatestStep(vector<int>& arr, int m) {
int len = arr.size();
if(len == m) return m;
vis.emplace(0); //相比于insert(),emplace()直接构造对象,效率更高
vis.emplace(len + 1);
for (int i = len - 1; i >= 0; i--){
auto it = vis.upper_bound(arr[i]); //返回第一个大于arr[i]的元素迭代器
int L = *prev(it), R = *it; //prev()获取一个距离指定迭代器 n 个元素的迭代器,n取正数时,向左移动。
if(arr[i] - L - 1 == m || R - arr[i] - 1 == m) //注意,要-1,因为是两个0位之差
return i;
vis.emplace(arr[i]); //分裂成两堆
}
return -1;
}
};
1563. 石子游戏 #记忆化搜索
题目链接
题意
几块石子排成一行 ,每块石子都有一个关联值,关联值为整数,由数组stoneValue 给出。
游戏中的每一轮:Alice 会将这行石子分成两个 非空行(长度不一定相等);Bob 负责计算每一行的值,即此行中所有石子的值的总和。Bob 会丢弃值最大的行,Alice 的得分为剩下那行的值(每轮累加)。如果两行的值相等,Bob 让 Alice 决定丢弃哪一行。下一轮从剩下的那一行开始。当只剩下一块石子时,游戏结束。Alice 的分数最初为 0 。
现要求 Alice 能够获得的最大分数 。
样例

分析
通过记忆化搜索来模拟即可,转移方程分三种情况,见下方代码。
class Solution {
private:
int sum[505] = {0}, dp[505][505] = {0};
int len;
public:
int dfs(int lo, int hi){
int mymax = 0;
if(lo <= 0 || hi > len) return 0;
if(hi - lo <= 0) return 0;
if(dp[lo][hi] > 0) return dp[lo][hi];
for (int i = lo; i <= hi; i++){
int presum = sum[i] - sum[lo - 1], latsum = sum[hi] - sum[i];
if(presum == latsum)
mymax = max(mymax, max(dfs(lo, i), dfs(i + 1, hi)) + presum);
else if(presum > latsum)
mymax = max(mymax, dfs(i + 1, hi) + latsum);
else
mymax = max(mymax, dfs(lo, i) + presum);
}
return dp[lo][hi] = mymax;
}
int stoneGameV(vector<int>& stoneValue) {
len = stoneValue.size();
if(len == 1) return 0;
if(len == 2) return min(stoneValue[0], stoneValue[1]);
memset(dp, -1, sizeof(dp));
for (int i = 0; i < len; i++) sum[i + 1] = sum[i - 1 + 1] + stoneValue[i];
return dfs(1, len);
}
};
LeetCode周赛#203 题解的更多相关文章
- Leetcode 周赛#202 题解
本周的周赛题目质量不是很高,因此只给出最后两题题解(懒). 1552 两球之间的磁力 #二分答案 题目链接 题意 有n个空篮子,第i个篮子位置为position[i],现希望将m个球放到这些空篮子,使 ...
- LeetCode周赛#204 题解
1566. 重复至少 K 次且长度为 M 的模式 #模拟 题目链接 题意 给定正整数数组 arr,请你找出一个长度为 m 且在数组中至少重复 k 次的模式. 模式 是由一个或多个值组成的子数组(连续的 ...
- Leetcode 周赛#201 题解
1545 找出第N个二进制字符串的第K位 #分治 题目链接 题意 给定正整数\(n(\leq 20)\)与\(k\),二进制串\(S_n\)形成规则有: \(S_1 = "0"\) ...
- Leetcode 周赛#200 题解
1535 找出数组游戏的赢家 #模拟+优化 题目链接 题意 给你一个由 不同 整数组成的整数数组 arr 和一个整数 k(\(1\leq k\leq1e9\)) .每回合游戏都在数组的arr[0] 和 ...
- Leetcode】周赛203 查找大小为M的最新分组
题意: 给你一个数组 arr ,该数组表示一个从 1 到 n 的数字排列.有一个长度为 n 的二进制字符串,该字符串上的所有位最初都设置为 0 . 在从 1 到 n 的每个步骤 i 中(假设二进制字符 ...
- LeetCode双周赛#33 题解
5480. 可以到达所有点的最少点数目 #贪心 题目链接 题意 给定有向无环图,编号从0到n-1,一个边集数组edges(表示从某个顶点到另一顶点的有向边),现要找到最小的顶点集合,使得从这些点出发, ...
- Leetcode 双周赛#32 题解
1540 K次操作转变字符串 #计数 题目链接 题意 给定两字符串\(s\)和\(t\),要求你在\(k\)次操作以内将字符串\(s\)转变为\(t\),其中第\(i\)次操作时,可选择如下操作: 选 ...
- 【Leetcode周赛】从contest-111开始。(一般是10个contest写一篇文章)
Contest 111 (题号941-944)(2019年1月19日,补充题解,主要是943题) 链接:https://leetcode.com/contest/weekly-contest-111 ...
- 【Leetcode周赛】从contest-41开始。(一般是10个contest写一篇文章)
Contest 41 ()(题号) Contest 42 ()(题号) Contest 43 ()(题号) Contest 44 (2018年12月6日,周四上午)(题号653—656) 链接:htt ...
随机推荐
- SQL Server 列存储索引 第二篇:设计
列存储索引可以是聚集的,也可以是非聚集的,用户可以在表上创建聚集的列存储索引(Clustered Columnstore Index)或非聚集的列存储索引(Nonclustered Columnsto ...
- CSS动画之转换模块
2D转换模块:注意点:1.可以类似于过渡模块一样简写,但是这里不是用逗号隔开而是用空格 2.2D的转换模块会修改元素的坐标系,所以旋转之后的平移就不是水平平移 格式:旋转:transform: rot ...
- Java学习的第三十四天
1.今天复习完了第十二章 2.有很多的方法不知道什么意思,也记不清该用什么方法. 3.明天写例题.
- php socket通信的简单实现
socket通信的原理在这里就不说了,它的用途还是比较广泛的,我们可以使用socket来做一个API接口出来,也可以使用socket来实现两个程序之间的通信,我们来研究一下在php里面如何实现sock ...
- python中的 异常处理(try...expect)
错误处理 关注公众号"轻松学编程"了解更多. 在程序运行的过程中,如果发生了错误,可以事先约定一个错误代码,这样就可以知道是否有错,以及出错的原因,在操作系统的调用中,返回错误码的 ...
- 利用VS2017制作软件安装包与卸载程序
本博客讲述如何利用VS2017制作安装包以及相应的卸载程序,并解决过程中可能遇到的问题 一.制作安装程序 1.打开VS2017,新建项目,选择如下图所示程序: 新建成功后,会出现如下图所示目录: 2. ...
- week01-绪论作业
一.有理数的抽象数据模型 ADT Rational { 数据对象: D={e1,e2|e1,e2属于ElemType类型}//ElemType为自定义的整数集合类型 数据关系: R={<e1,e ...
- 五分钟看懂抓包神技:DPDK
我是一个网络监控软件,我被开发出来的使命就是监控网络中进进出出的所有通信流量. 一直以来,我的工作都非常的出色,但是随着我监控的网络越来越庞大,网络中的通信流量也变得越来越多,我开始有些忙不过来了,逐 ...
- 手机运行Linux系统,可以办公,可以上网,太爽了!
之前用 Termux 编程一直都是在黑乎乎的命令行敲代码,有多少人知道其实可以在手机上用 Termux 构建一个包含桌面环境的 Linux 系统呢. 这个构建出的 linux 系统,可以显示出桌面,可 ...
- 【】JSON和JSONP
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html http://www.cnblogs.com/do ...