1545 找出第N个二进制字符串的第K位 #分治

题目链接

题意

给定正整数\(n(\leq 20)\)与\(k\),二进制串\(S_n\)形成规则有:

  • \(S_1 = “0”\)

  • 当\(i>1\)时,\(S_i = S_{i-1}+“1”+reverse(invert(S_{i-1}))\)

    其中\(reverse(x)\)表示左右反转字符串x,\(invert(x)\)表示翻转x中的每一位(0->1,1->0)

现要返回\(S_n\)的第\(k\)位字符。

如:\(n=3,k=1\),可以得到\(S_3=“0111001”\),其第一位为"0",故返回"0"

分析

本来想打表,但最后的串实在是长。我们不必从n=1一步步模拟整个过程,而是自顶而下深入递归,只关心第\(k\)位属于上一步形成的01串的哪个位置哪个字符。

我们容易推出,对于\(S_n\)形成的串为\(2^n-1\)长度的01串,我们比较\(k\)与\(2^{n-1}\)的大小:

  • 如果\(k=2^{n-1}\),它在串最中间,字符为"1",直接返回即可
  • 如果\(k<2^{n-1}\),它在当前串的左部分,由串的形成规则可知,串左部分是经上一轮的串直接复制得到的,那么递归\(n-1\)次操作的第\(k\)位即可
  • 如果\(k>2^{n-1}\),由串的形成规则,串右部分是经过上一轮串的反转+翻转得到的,那么当前的第k位是由上一轮的\(2^n-1-k+1\)位置得到的,当然别忘了对返回结果的字符进行取反操作!
class Solution {
public:
char Trans(char now) {
return (now == '1') ? '0' : '1';
}
char findKthBit(int n, int k) {
if (n == 1) return '0';
int len = 1 << (n - 1);
if (k == len) return '1';
else if (k < len) return findKthBit(n - 1, k);
else {
return Trans(findKthBit(n - 1, (len << 1) - k));
}
}
};

1546 和为目标值的最大数目不重叠非空子数组数目 #前缀和 #哈希表 #线性DP

题目链接

题意

给定数组 nums(长度不大于\(1e5\)) 和一个整数 target 。现要返回 非空不重叠 子数组的最大数目,且每个子数组中数字和都为 target 。

样例

nums = [-1,3,5,1,4,2,-9], target = 6,总共有 3 个子数组和为 6 。 $([5,1], [4,2], [3,5,1,4,2,-9]) $但只有前 2 个是不重叠的。

分析

dp[i]表示前i位满足要求的子数组个数;sum表示[1, size]的前缀和(先假定从1计数)

当\(i>0\)显然dp[0] = 0;当\(i>0\)时,有两种情况:

  • 存在这样的\(pos(\leq i) st.sum[i]-sum[pos]==target\),

    • 我们找到\([pos, i]\)的合法子数组,于是dp[i] 可以由dp[pos]+1转移
    • [pos, i]的子数组长度可能太长,以至于覆盖了该区间的几个合法子数组,那么dp[i]也可以由dp[i-1]转移

    即得到转移方程:\(dp[i] = max(dp[i-1], dp[pos]+1)\)

  • 不存在这样的\(pos\),显然转移方程只能为\(dp[i] = dp[i-1]\)

class Solution {
private:
int dp[100005] = {0};
public:
int maxNonOverlapping(vector<int>& nums, int target) {
map<int, int> mymap;
int sum = 0; mymap[0] = 0;
for (int i = 1; i <= nums.size(); i++) {
sum += nums[i - 1];
if (mymap.count(sum - target)) { //是否存在sum[pos]满足sum[i]-sum[pos]=target
int pos = mymap[sum - target];
dp[i] = max(dp[i - 1], dp[pos] + 1);
}
else {
dp[i] = dp[i - 1];
}
mymap[sum] = i; //记录前缀和sum的最新位置
}
return dp[nums.size()];
}
};

1547 切棍子的最小成本 #区间DP

题目链接

题意

给定长度为\(n\)个单位的木棍,及记录你要将棍子切开的位置数组\(cuts[i]\),现要你按\(cuts[i]\)记录的位置按一定顺序切割木棍,使得成本最小,并求其值。其中每次切割的成本是当前要切割的棍子的长度。

分析

显然是石子合并的变式,区间DP题,不过我们需要预处理下每个切割位置之间的长度(该位置的序号-前一位置的序号),同时将代价数组sum[]从1计数,便于DP

class Solution {
private:
int sum[105] = { 0 };
int dp[105][105];
public:
int cost(int lo, int hi) {
return sum[hi] - sum[lo];
}
void Init(int maxlen, vector<int>& cuts, int n) {
sort(cuts.begin(), cuts.end());
for (int i = 1; i <= maxlen; i++)
for (int j = 1; j <= maxlen; j++)
dp[i][j] = 0x3f3f3f3f;
sum[1] = cuts[0]; dp[1][1] = dp[maxlen][maxlen] = 0;
for (int i = 2; i <= cuts.size(); i++) {
dp[i][i] = 0;
sum[i] = sum[i - 1] + cuts[i - 1] - cuts[i - 2];
}
sum[maxlen] = sum[maxlen - 1] + n - cuts[cuts.size() - 1];
}
int minCost(int n, vector<int>& cuts) {
int maxlen = cuts.size() + 1;
Init(maxlen, cuts, n);
for (int len = 2; len <= maxlen; len++) {
for (int i = 1; i + len - 1 <= maxlen; i++) {
int j = i + len - 1;
for (int k = i; k < j; k++)
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + cost(i - 1, j));
}
}
return dp[1][maxlen];
}
};

Leetcode 周赛#201 题解的更多相关文章

  1. Leetcode 周赛#202 题解

    本周的周赛题目质量不是很高,因此只给出最后两题题解(懒). 1552 两球之间的磁力 #二分答案 题目链接 题意 有n个空篮子,第i个篮子位置为position[i],现希望将m个球放到这些空篮子,使 ...

  2. LeetCode周赛#204 题解

    1566. 重复至少 K 次且长度为 M 的模式 #模拟 题目链接 题意 给定正整数数组 arr,请你找出一个长度为 m 且在数组中至少重复 k 次的模式. 模式 是由一个或多个值组成的子数组(连续的 ...

  3. LeetCode周赛#203 题解

    1561. 你可以获得的最大硬币数目 #贪心 题目链接 题意 有 3n 堆数目不一的硬币,你和你的朋友们打算按以下方式分硬币: 每一轮中,你将会选出 任意 3 堆硬币(不一定连续). Alice 将会 ...

  4. Leetcode 周赛#200 题解

    1535 找出数组游戏的赢家 #模拟+优化 题目链接 题意 给你一个由 不同 整数组成的整数数组 arr 和一个整数 k(\(1\leq k\leq1e9\)) .每回合游戏都在数组的arr[0] 和 ...

  5. 【LeetCode】201. Bitwise AND of Numbers Range 解题报告(Python)

    [LeetCode]201. Bitwise AND of Numbers Range 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/prob ...

  6. LeetCode双周赛#33 题解

    5480. 可以到达所有点的最少点数目 #贪心 题目链接 题意 给定有向无环图,编号从0到n-1,一个边集数组edges(表示从某个顶点到另一顶点的有向边),现要找到最小的顶点集合,使得从这些点出发, ...

  7. Leetcode 双周赛#32 题解

    1540 K次操作转变字符串 #计数 题目链接 题意 给定两字符串\(s\)和\(t\),要求你在\(k\)次操作以内将字符串\(s\)转变为\(t\),其中第\(i\)次操作时,可选择如下操作: 选 ...

  8. 【Leetcode周赛】从contest-111开始。(一般是10个contest写一篇文章)

    Contest 111 (题号941-944)(2019年1月19日,补充题解,主要是943题) 链接:https://leetcode.com/contest/weekly-contest-111 ...

  9. 【Leetcode周赛】从contest-41开始。(一般是10个contest写一篇文章)

    Contest 41 ()(题号) Contest 42 ()(题号) Contest 43 ()(题号) Contest 44 (2018年12月6日,周四上午)(题号653—656) 链接:htt ...

随机推荐

  1. python基础二:循环

    python 中循环的方式有两种: 一,for 循环  单向循环 可以用来遍历字符串,列表,元组,字典等 for value in 被遍历对象: print(value) 遍历字典dict的时候稍有不 ...

  2. 假如把Redis服务器们拉到一个群,看看他们是怎么工作的?

    我是Redis,一个叫Antirez的男人把我带到了这个世界上. 那天,Redis基友群里,许久未见的大白发来了一条消息··· 于是,大白拉了一个新的群 以后的日子中,咱们哥仨相互配合,日常工作中最多 ...

  3. 浅谈 Tarjan 算法

    目录 简述 作用 Tarjan 算法 原理 出场人物 图示 代码实现 例题 例题一 例题二 例题三 例题四 例题五 总结 简述 对于初学 Tarjan 的你来说,肯定和我一开始学 Tarjan 一样无 ...

  4. 快快使用ModelArts,零基础小白也能玩转AI!

    摘要: 走过路过不要错过,看Copy攻城狮如何借力华为云ModelArts玩转AI. "自2018年10月发布以来,ModelArts累计服务了众多行业十几万开发者,通过基础平台的完备性和面 ...

  5. 浅谈MVP

    MVP是什么 MVP:Model-View-PresenterModel:表示数据提供者:View:表示数据展示:Presenter:是M与V沟通的桥梁. MVP工作方式 UI:告知Presenter ...

  6. How to using expression setup BackgroundColor AX2012 SSRS Report[AX2012]

    tile label using [#99ccff] property BackgroundColor - > expression =Iif(Fields!Flag.Value = " ...

  7. C# 时间格式处理

    C#的常用时间格式意义: 1字符"y"---year,年,yy显示13,yyyy显示2013 2字符"M"---Month,月份,M显示5,MM显示05 3字符 ...

  8. python动态规划

    动态规划: 动态规划表面上很难,其实存在很简单的套路:当求解的问题满足以下两个条件时, 就应该使用动态规划:        主问题的答案 包含了 可分解的子问题答案 (也就是说,问题可以被递归的思想求 ...

  9. 【linux】-Makefile简要知识+一个通用Makefile

    目录 Makefile Makefile规则与示例 为什么需要Makefile Makefile样式 先介绍Makefile的两个函数 完善Makefile 通用Makefile的使用 通用的Make ...

  10. layui的laypage实现分页/查询

    最开始我的数据绑定使用的razor语法来绑定的 就像下面这样 @if (ViewBag.listBlog != null) { foreach (var item in ViewBag.listBlo ...