leetcode个人秋季赛总结(太菜了,只写出两题)
Posted C_YCBX Py_YYDS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode个人秋季赛总结(太菜了,只写出两题)相关的知识,希望对你有一定的参考价值。
T1: 无人机方阵
此题有坑,直接哈希计数后,注意不能单一的+1计数,因为可能存在多个相同的元素重叠,应该+上绝对值。
OJ平台
解题代码
class Solution {
public:
int minimumSwitchingTimes(vector<vector<int>>& source, vector<vector<int>>& target) {
int check[10004];memset(check,0,sizeof(check));
int n = source.size(),m = source[0].size();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
check[source[i][j]]++;
check[target[i][j]]--;
}
}
int cnt = 0;
for(int i=0;i<=10000;i++){
if(check[i]<0)
cnt+=abs(check[i]);
}
return cnt;
}
};
T2:心算挑战
很多大佬都是简短的贪心写法,我是傻乎乎花了两小时写了个dp😂
OJ平台
解题思路
当需要形成一个奇数时,我们必须是一奇一偶,当需要形成一个偶数时我们必须两偶或者两奇。
- 根据上面的特性,我们构建dp关系:
dp[0][i] 代表取了 i 个元素且结果为偶数的情况的最大值。
dp[1][i] 代表取了 i 个元素且结果为奇数的情况的最大值。
- 转移方程:
dp[偶][i] = max(dp[偶][i],dp[奇][i-1]+odd[pos])
dp[偶][i] = max(dp[偶][i],dp[偶][i-1]+even[pos])
dp[奇][i] = max(dp[奇][i],dp[奇][i-1]+even[pos])
dp[奇][i] = max(dp[奇][i],dp[偶][i-1]+odd[pos])
- 实际上奇数的更新情况只要写其中一个就行了,因为这两个值肯定是相同的。
现在状态转移方程想好了,但是怎么保证 odd 和 even 中取值每次都是最大且不重复的呢?
我们将odd和even按照从大到小排序并且定义一个结构体:
//由于排序后总是从左到右取值
//evenpos表示当前状态下even数组中取到了哪个下标
//oddpos表示当前状态下odd数组中取到了哪个下标
struct ss {
int val;
int evenpos;
int oddpos;
ss(): val(0), evenpos(0), oddpos(0) {}
};
解题代码
class Solution {
public:
//用于动态规划的结构体,其中val存下当前状态的值,
//evenpos表示当前状态偶数选择到了哪一个位置,oddpos表示奇数选择到了哪一个位置
struct ss {
int val;
int evenpos;
int oddpos;
ss(): val(0), evenpos(0), oddpos(0) {}
};
int maxmiumScore(vector<int>& cards, int cnt) {
//创建奇偶结果统计
vector<int>odd, even;
for (int i = 0; i < cards.size(); i++) {
if (cards[i] % 2) {
odd.emplace_back(cards[i]);
} else {
even.emplace_back(cards[i]);
}
}
//为奇偶数组从大到小排序,方便选择
sort(odd.rbegin(), odd.rend());
sort(even.rbegin(), even.rend());
//创建dp数组遍历答案
ss dp[2][cnt + 1];
//用于记录该状态是否被更新,防止出现无答案的cnt次状态被转移
bool check[2][cnt + 1];
memset(check, 0, sizeof(check));
//base case:
if (even.size()) {
dp[0][1].val = even[0]; dp[0][1].evenpos++;
check[0][1] = 1;
}
if (odd.size()) {
dp[1][1].val = odd[0]; dp[1][1].oddpos++;
check[1][1] = 1;
}
//开始进行更新状态转移,dp[0][i].val代表取i个数为偶数时的最大值,dp[1][i].val为取奇数时的最大值
//为了解决每次加的奇偶数不重复的问题,所以结构体添加了每个状态下的奇偶最新下标取值(反正已经排好序了)
for (int i = 2; i <= cnt; i++) {
if (check[1][i - 1] && dp[1][i - 1].oddpos < odd.size() && dp[0][i].val < dp[1][i - 1].val + odd[dp[1][i - 1].oddpos]) {
check[0][i] = 1;
dp[0][i].val = dp[1][i - 1].val + odd[dp[1][i - 1].oddpos];
dp[0][i].oddpos = dp[1][i - 1].oddpos + 1;
dp[0][i].evenpos = dp[1][i - 1].evenpos;
}
if (check[0][i - 1] && dp[0][i - 1].evenpos < even.size() && dp[0][i].val < dp[0][i - 1].val + even[dp[0][i - 1].evenpos]) {
check[0][i] = 1;
dp[0][i].val = dp[0][i - 1].val + even[dp[0][i - 1].evenpos];
dp[0][i].oddpos = dp[0][i - 1].oddpos;
dp[0][i].evenpos = dp[0][i - 1].evenpos + 1;
}
if (check[0][i - 1] && dp[0][i - 1].oddpos < odd.size() && dp[1][i].val < dp[0][i - 1].val + odd[dp[0][i - 1].oddpos]) {
check[1][i] = 1;
dp[1][i].val = dp[0][i - 1].val + odd[dp[0][i - 1].oddpos];
dp[1][i].oddpos = dp[0][i - 1].oddpos + 1;
dp[1][i].evenpos = dp[0][i - 1].evenpos;
}
//由于奇数情况只需要更新一种就行了
// if (check[1][i - 1] && dp[1][i - 1].evenpos < even.size() && dp[1][i].val < dp[1][i - 1].val + even[dp[1][i - 1].evenpos]) {
// check[1][i] = 1;
// dp[1][i].val = dp[1][i - 1].val + even[dp[1][i - 1].evenpos];
// dp[1][i].oddpos = dp[1][i - 1].oddpos;
// dp[1][i].evenpos = dp[1][i - 1].evenpos + 1;
// }
}
return dp[0][cnt].val;
}
};
总结
- 求稳:一旦某种方法一直错误,不要怀疑自己的思路,肯定是哪个小细节出错了。
- 求快:不要因小失大,要总览全题,不要因为一道题而放弃了所有。
学到了什么:
在这次中自己按照思路写出了DP,这算是最大的收获了!
以上是关于leetcode个人秋季赛总结(太菜了,只写出两题)的主要内容,如果未能解决你的问题,请参考以下文章