Smell Billy 2021届
APP 内打开
分享
5

字节跳动周赛专场,来看看嘛?

题目1:5625. 比赛中的配对次数


思路:模拟

代码:

```c++

class Solution {

public:

int numberOfMatches(int n) {

int ret = 0;

while(n > 1) {

int cur = n / 2; // 比赛次数,也是晋级队伍数量

ret += cur; // 计入比赛场次

n -= cur * 2; // 轮空队伍数量

n += cur; // 晋级队伍 + 轮空队伍 = 剩余队伍数量

}

return ret;

}

};

```


复杂度分析:

时间复杂度为 O(lgn),空间复杂度为 O(1)。



题目2:5626. 十-二进制数的最少数目

思路:模拟

求字符串中出现的最大的数字即可


代码:

```c++

class Solution {

public:

int minPartitions(string n) {

int ret = 0;

for(char c : n) {

ret = max(ret, c - '0');

}

return ret;

}

};

```


复杂度分析:

时间复杂度为 O(n),空间复杂度为 O(1)。



题目3:5627. 石子游戏 VII

思路:动态规划

对于两个选手,希望的都是尽可能扩大两人得分之间的差值,维护二维数组 $dp[i][j]$ 表示在 $[i, j]$ 区间内删除最左边或者最右边的数后得分的更大差值。如果删除 $stones[i]$,得分为 $[i + 1, j]$ 区间的石子值总和(可以提前维护前缀和通过 $O(1)$ 得到),然后第二个人能得到的最大差值为 $dp[i + 1][j]$,同理,如果删除 $stones[j]$,得分为 $[i, j - 1]$ 区间的石子值总和,第二个人能得到的最大差值为 $dp[i][j - 1]$。


由于 Alice 希望提高差值,Bob也希望提高差值,两人希望的差值方向不同,所以更新时需要比较得分与下一个人差值的**差**,也即 $dp[i][j] = max(score_1 - dp[i + 1][j], score_2 - dp[i][j - 1])$


由于一个区间的差值 $dp[i][j]$ 是由更小的区间内的差值得来的,所以遍历更新是要维护区间长度从小到大。


特别地,$ i = j$ 时,说明当前数组只剩下一个元素,此时删除该元素无法得分,所以初始化 $dp[i][i] = 0$。


代码:

```c++

class Solution {

public:

int stoneGameVII(vector& a) {

int n = a.size();

vector v(n + 1, 0);

for(int i = 1; i <= n; i++) v[i] = v[i - 1] + a[i - 1];

vector> dp(n, vector(n, 0));

for(int k = 1; k < n; k++) {

for(int i = 0; i < n; i++) {

int j = i + k;

if(j == n) break;

dp[i][j] = max(v[j + 1] - v[i + 1] - dp[i + 1][j],\

v[j] - v[i] - dp[i][j - 1]);

}

}

return dp[0][n - 1];

}

};


```


复杂度分析:

时间复杂度为 O(n^2),相当于遍历了所有子区间,共有 $n + n - 1 + ... + 1 = n(n + 1)/2 个子区间

空间复杂度为 O(n^2),维护了二维数组



题目4:5245. 堆叠长方体的最大高度

思路:动态规划

如果两个长方体可以拼接,根据题意,长宽高都需要满足同样的大小关系,则不管从什么方向都可以拼接。为了提高拼接后的长度,我们只需要将这三个指标中较长的一个单独提取出来作为高。


因此,我们先对每个长方体进行长宽高排序(将最长的作为高),然后对所有长方体进行排序,再遍历更新最大值即可(类似于最大上升子序列)


代码:

```c++

class Solution {

public:

int maxHeight(vector>& a) {

int n = a.size();

for (auto &aa : a) sort(aa.begin(), aa.end());

sort(a.begin(), a.end());

vector dp(n);

int ret = 0;

for(int i = 0; i < n; i++) {

for(int j = 0; j < i; j++) {

if(a[j][1] <= a[i][1] && a[j][2] <= a[i][2]) {

dp[i] = max(dp[i], dp[j]);

}

}

dp[i] += a[i][2]; // 加上高度

ret = max(ret, dp[i]);

}

return ret;

}

};

```


复杂度分析:

时间复杂度为 O(n^2),空间复杂度为 O(n^2)


发布时间:2020年12月13日
用户头像
我来说两句…
共 5 条评论
七堇年。 哥伦比亚大学·2022届
🐂
2020年12月14日 回复
一叶扁舟白梦 新加坡国立大学·2022届
ddddddd
2020年12月14日 回复
🌞 云南大学·2022届
2020年12月13日 回复
我要向前进 . 天津理工大学·2022届
这回看见真大佬了
2020年12月13日 回复
向往鹰的飞翔 浙江工业大学·2022届
好全啊
2020年12月13日 回复