5492. 分割字符串的方案数 #组合公式 #乘法原理 #区间分割

题目链接

题意

给定01二进制串\(s\),可将\(s\)分割为三个非空 字符串\(s_1,s_2,s_3\),即(\(s_1+s_2+s_3=s\))。现要你求出分割\(s\)的方案数,保证\(s_1,s_2,s_3\)中字符1的数目相同(对\(1e9+7\)取模),他们的长度不一定相等

分析

举个例子,01100011000101串,可以知道三个子串必须包含2个'1',我们观察到左子串的界限,可以如下划分:011|000110001010110|001100010101100|011000101011000|11000101,共四种划分方案;同理对于右子串,共有四种划分方案。当我们将左右子串由于中间子串的间隔,使得左右子串的确定不会相互影响,同时中间子串也相应确定下来,通过乘法原理,总方案数=左子串划分方案数\(\times\)右子串划分方案数=16。

然而,别忘了诸如00000等只包含'0'的串,三子串的划分确定会相互影响,比如0|000|0000|0|0等,此时我们可以用高中所学排列组合的“挡板法”确定下来,即串长为\(n\),有\(n-1\)空位,可以插入两个挡板,即\(C^2_{n-1}\)。

typedef long long ll;
class Solution {
private:
int sum[100005];
const int MOD = 1e9 + 7;
public:
int numWays(string s) {
int n = s.size();
for (int i = 0; i < n; i++) //利用前缀和统计1的数目
sum[i + 1] = sum[i + 1 - 1] + (s[i] == '1');
if(sum[n] == 0){ //特判全部为0的串
ll ans = (ll)(n - 1) * (ll)(n - 2) / (ll)2;
return ans % MOD;
}
if(sum[n] % 3 != 0) return 0; //特判不含有3的整数倍的串,无法分割
else{
int diff = sum[n] / 3; //确定每个子串中的'1'数量
ll a = 0, b = 0;
for (int i = 1; i <= n - 2; i++) //确定左子串可拓展的长度
if(sum[i] == diff) a++;
for (int i = n; i >= 2; i--) //确定右子串可拓展的长度
if(sum[n] - sum[i - 1] == diff) b++;
ll ans = (a % MOD) * (b % MOD); //乘法原理
return ans % MOD;
}
}
};

5493. 删除最短的子数组使剩余数组有序 #归并排序 #区间分割

题目链接

题意

给定整数数组arr ,你需要删除一个子数组(原数组中连续的一个子序列,可以为空),使得arr中剩下的元素是 非递减的。现要你求出满足题目要求的最短子数组的长度。

分析

感谢@Liuyh思路。

题目要求只能删除一个子数组,也就说子数组内部存在一小段是非递减的,但也必须要删去。一般地,我们一定是从数组中间部分进行删除(只删除左部分或只删除右部分属于退化情况),即[....|XXXX|....](X表示要删除的部分)。 删除中间的子数组(并不代表最终删除子数组),意味着剩余前后两个子数组都符合非递减,这一操作需要前后两个指针,分别将两数组边界确定下来。代码中左子数组为[0, lo],而右子数组为[hi, len-1]。比如原数组[1,2,3,10,4,2,3,5],确定出左子数组 [1,2,3,10]lo指向10,右子数组[2, 3, 5]。中间数组删除长度为\(hi-lo+1\)

现在我们要合并上述两个子数组,需要用到归并排序的思想,一旦发现右子数组比左子数组还大的元素,其中一个元素给舍弃掉(无需考虑是删除左数组的还是右数组的)。举个例子:

  • [1,2,3,10][2,3,5]
  • 由于1<2,此时[2,3,10][2,3,5]
  • 由于2<=2,此时[3,10][2,3,5]
  • 由于3>2,舍弃右子数组的2,左子数组跳过3ans++,此时[10][3,5]
  • 由于10>3,舍弃10,得到 [][5],算法结束。
class Solution {
public:
int findLengthOfShortestSubarray(vector<int>& arr) {
int lo = 0, len = arr.size(), hi = arr.size() - 1;
if(len == 1) return 0; //特判:一个元素就无需删除了
while(lo + 1 < len && arr[lo] <= arr[lo + 1]) lo++;
//开始分割,确定左区间的右端点,注意,是往后递推,这样能够保证lo最终指向的依然是非降左子序列的右端点
if(lo + 1 == len) return 0; //说明原数组是个非降序列,直接返回0
while(lo < hi && arr[hi - 1] <= arr[hi]) hi--;
if(hi == lo && hi == 0) return len - 1; //说明原数组是完全递减区间 int ans = hi - lo - 1; //统计分割出来的区间
int i = 0, j = hi; while(i <= lo && j < len){ //合并区间
if(arr[i] <= arr[j]) i++; //以左序列为基准
else if(arr[i] > arr[j]){ //因为题目要求从左至右递增
i++; j++;//注意!一定是两个指针同时前进,因为你不知道哪个子数组影响最终结果
ans++;
}
}
return ans;
}
};

5494. 统计所有可行路径 #记忆化搜索

题目链接

题意

有若干个城市,第i个城市有location[i]值。给定你城市出发起点start、目的地城市finish、初始汽油总量fuel。每当你从城市j移动到城市i时,消耗的油量为|location[j] - location[i]|。你要保证剩余的油量非负,方能移动到其他城市。同时,你可以经过任意城市超过一次(包括startfinish)。现要你求出从startfinish可能路径的数目(需取模)

分析

观察到数据范围\(fuel\leq200\)及\(locations.len\leq100\),直接记忆化搜索即可。但注意,尽管你此时到达了finish城市,只要你油量足够,仍能够移动到其他城市。

dp[i][j]表示当前起点为i,剩余油量j的总方案数。

要注意,我直接把dp数组放到全局变量的时候,出锅了不少qaq,别忘了在类内要对这个全局变量初始化一下,同时记忆化搜索一般赋值为-1较为稳妥。

typedef long long ll;
int dp[105][205];
const int MOD = 1e9 + 7;
class Solution {
public:
int dfs(vector<int>& locations, int start, int finish, int fuel){
if(dp[start][fuel] != -1) return dp[start][fuel];
ll ans = 0; int len = locations.size();
if(start == finish) ans++;
for (int i = 0; i < len; i++){
int diff = abs(locations[i] - locations[start]);
if(start == i) continue;
if(fuel - diff >= 0){
ans = (ans + dfs(locations, i, finish, fuel - diff)) % MOD;
}
}
dp[start][fuel] = (ans % MOD);
return dp[start][fuel];
}
int countRoutes(vector<int>& locations, int start, int finish, int fuel) {
memset(dp, -1, sizeof(dp));
return dfs(locations, start, finish, fuel);
}
};

LeetCode双周赛#34的更多相关文章

  1. leetcode 双周赛9 进击的骑士

    一个坐标可以从 -infinity 延伸到 +infinity 的 无限大的 棋盘上,你的 骑士 驻扎在坐标为 [0, 0] 的方格里. 骑士的走法和中国象棋中的马相似,走 “日” 字:即先向左(或右 ...

  2. leetcode 双周赛9 找出所有行中最小公共元素

    给你一个矩阵 mat,其中每一行的元素都已经按 递增 顺序排好了.请你帮忙找出在所有这些行中 最小的公共元素. 如果矩阵中没有这样的公共元素,就请返回 -1. 示例: 输入:mat = [[,,,,] ...

  3. [每日一题2020.06.16] leetcode双周赛T3 5423 找两个和为目标值且不重叠的子数组 DP, 前缀和

    题目链接 给你一个整数数组 arr 和一个整数值 target . 请你在 arr 中找 两个互不重叠的子数组 且它们的和都等于 target .可能会有多种方案,请你返回满足要求的两个子数组长度和的 ...

  4. LeetCode双周赛#36

    1604. 警告一小时内使用相同员工卡大于等于三次的人 题目链接 题意 给定两个字符串数组keyName和keyTime,分别表示名字为keytime[i]的人,在某一天内使用员工卡的时间(格式为24 ...

  5. LeetCode双周赛#35

    1589. 所有排列中的最大和 #差分 #贪心 题目链接 题意 给定整数数组nums,以及查询数组requests,其中requests[i] = [starti, endi] .第i个查询求 num ...

  6. LeetCode双周赛#33 题解

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

  7. Leetcode 双周赛#32 题解

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

  8. LeetCode第8场双周赛(Java)

    这次我只做对一题. 原因是题目返回值类型有误,写的是 String[] ,实际上应该返回 List<String> . 好吧,只能自认倒霉.就当涨涨经验. 5068. 前后拼接 解题思路 ...

  9. LeetCode 第 15 场双周赛

    1287.有序数组中出现次数超过25%的元素 1288.删除被覆盖区间 1286.字母组合迭代器 1289.下降路径最小和 II 下降和不能只保留原数组中最小的两个,hacked. 1287.有序数组 ...

随机推荐

  1. 编写shell脚本的规范

    目录 编写shell脚本的一些规范 解释器 添加脚本版本和注释功能 添加脚本调试 变量命名 全局变量和局部变量 命名规范 函数命名 脚本命名 函数 引用模块或文件 脚本日志 配置文件 其他 编写she ...

  2. 【源码】spring循环引用

    spring在单例,非构造方法注入的情况下允许循环依赖 1.循环依赖 a引用b,b引用a.a创建的时候需要b,但是b没有创建,需要先去创建b,b创建的时候又没有a,这就出现的循环依赖的问题 2.为什么 ...

  3. modbus协议开关量采集模块

    modbus协议开关量采集模块是指的使用Modbus协议的进行信号的采集与控制的一种设备. Modbus 协议设备都具有唯一的 Modbus 地址,众山 DTU 默认 Modbus 地址为 100,用 ...

  4. Java学习的第二十八天

    1.Scanner类 序列化 将实体类标注为可序列化 2.不明白 3.明天学习反序列化,transient关键字,序列化一组对象

  5. 请教:Effective Java 第120页,代码运行未重现报错

    在阅读<Effective Java 第二版>时,尝试编写重现第120页问题,发现未重现报错信息,可以正常运行并输出结果.有知道原因的请在评论中留言指导一下,谢谢!!! 问题如下

  6. Ordering Cows

    题意描述 好像找不到链接(找到了请联系作者谢谢),所以题目描述会十分详细: Problem 1: Ordering Cows [Bruce Merry, South African Computer ...

  7. redis的rdb与aof持久化机制

    Redis提供了两种持久化方案:RDB持久化和AOF持久化,一个是快照的方式,一个是类似日志追加的方式 RDB快照持久化 RDB持久化是通过快照的方式,即在指定的时间间隔内将内存中的数据集快照写入磁盘 ...

  8. P6773 [NOI2020]命运

    整体DP 很明显计算答案需要用容斥计算,如果暴力容斥的话,就是枚举哪些路径不符合条件,在这些路径的并集中的边都不能取,其他边任意取,设当前取了$i$条路径,那么对答案的贡献是$(-1)^i2^{n-1 ...

  9. Java_垃圾回收机制(未掌握)

    垃圾回收机制 任何一种垃圾回收算法一般要做两件基本事情: 发现无用的对象(没有任何变量引用该对象) 回收无用对象占用的内存空间 垃圾回收相关算法: 引用计数法, 引用可达法 分代垃圾回收机制: 不同的 ...

  10. 回顾MySql的一些基本的增删改查

    ---恢复内容开始--- 回顾数据库的一些简单的增删查改的操作语法与注意点,来自菜鸟教程https://www.runoob.com/mysql/mysql-tutorial.html 关于数据库的操 ...