题目
- 比赛中的配对次数
-
十-二进制数的最少数目
-
石子游戏 VII
-
堆叠长方体的最大高度
思路与算法
- 比赛中的配对次数
两两比赛,淘汰剩一支队伍,每次比赛淘汰一支队伍,因此答案为n-1 - 十-二进制数的最少数目
找到这些数里面最大的值,然后返回即可,相当于消消乐,简单做法呢用栈,再简单就直接遍历。注意字符串与数字之间的转换关系。 - 石子游戏 VII
很久没写dp了最近期末,这道题属于刚刚好10分钟写得出来的地步,建议Bob锤死Alice,石子游戏之前写过很多了,基本都是dp,直接见注释,问题不大,思路理清楚就行了,画个决策树的图会比较清晰。 - 堆叠长方体的最大高度
本题10分钟没思路,题解参考自**@zerotrac** 零神官方题解。但我一开始没想明白怎么转换状态,简单的二维dp。根据其C++代码写了Java的版本交作业
代码实现
- 比赛中的配对次数
class Solution {
public:
int numberOfMatches(int n) {
return n-1;
}
};
- 十-二进制数的最少数目
class Solution {
public int minPartitions(String n) {
int res = 0;
for (int i = 0; i < n.length(); i++) {
if (n.charAt(i) - '0' > res) {
res = n.charAt(i) - '0';
}
if (res == 9)
return res;
}
return res;
}
}
- 石子游戏 VII
class Solution {
public int stoneGameVII(int[] stones) {
// 典型的dp题
int len = stones.length;
int [][] dp = new int[len][len];
for (int i = 1; i < len; i++) {
for (int j = i; j < len; j++) {
int a = j - i;
int b = j;
if (a + 1 == b) {
dp[a][b] = Math.max(stones[a],stones[b]);
} else if (a + 2 == b) {
/*
如果相差为2,有3个石子,则第一次选择左边的话,a的最大收益为s[b] + s[b-1],
那么b的最大收益为max(s[b-1],s[b]),那么最大差值应该为min(s[b-1],s[b])
记得先判断左边和右边哪一个小,也就是a先选择的是哪一边
*/
if (stones[a] > stones[b]) {
dp[a][b] = Math.min(stones[a],stones[a+1]);
} else {
dp[a][b] = Math.min(stones[b-1],stones[b]);
}
} else {
int selA = Math.min(dp[a+2][b] + stones[a+1], dp[a+1][b-1] + stones[b]);
int selB = Math.min(dp[a][b-2] + stones[b-1], dp[a+1][b-1] + stones[a]);
dp[a][b] = Math.max(selA,selB);
}
}
}
return dp[0][len - 1];
}
}
- 堆叠长方体的最大高度
class Solution {
public int maxHeight(int[][] cuboids) {
// 体内排序
for (int[] cuboid : cuboids) {
Arrays.sort(cuboid);
}
// 体间排序
Arrays.sort(cuboids, (o1, o2) -> {
if (o1[0] != o2[0]) {
return Integer.compare(o1[0], o2[0]);
} else if (o1[1] != o2[1]) {
return Integer.compare(o1[1], o2[1]);
} else {
return Integer.compare(o1[2], o2[2]);
}
});
// dp[i]表示以第i个长方体为底长方体堆的最大高度
int[] dp = new int[cuboids.length];
int maxAns = 0;
for (int i = 0; i < cuboids.length; i++) {
for (int j = 0; j < i; j++) {
if (cuboids[j][1] <= cuboids[i][1] && cuboids[j][2] <= cuboids[i][2]) {
dp[i] = Math.max(dp[i], dp[j]);
}
}
dp[i] += cuboids[i][2];
// 更新最大高度
maxAns = Math.max(maxAns, dp[i]);
}
return maxAns;
}
}
复杂度分析
- 本周题目基本不涉及复杂度的难点,巩固了动态规划的概念。
- 考试期间事情略多,周赛只能偶尔打打了。