文章目录
- 乒乓球筐(哈希)
- 题解
- 代码
- 组队竞赛
- 题解
- 代码
- 删除相邻数字的最大分数(线性dp)
- 题解
- 代码
乒乓球筐(哈希)
题目链接
题解
1. 两个哈希表
先统计第一个字符串中的字符个数,再统计第二个字符串中的字符个数,如果第一个字符串中的字符个数大于等于第二个字符串中的字符个数,返回true,否则返回false
2. 用一个哈希表
先统计第一个字符串中的字符个数,然后再减去第二个字符串中的字符个数,如果hash表中某个字符的个数小于0就说明该字符不在第一字符串中,而只在第二个字符串中,返回false,否则返回true
代码
#include <iostream>
using namespace std;int main()
{string s,t;while(cin >> s >> t)// 未知组数的输入{int hash[26] = {0};int n = t.size();int flag = 1;for(auto ch : s){hash[ch - 'A']++;}for(int i = 0;i < n;i++){hash[t[i] - 'A']--;if(hash[t[i] - 'A'] < 0) {flag = 0;cout << "No" << '\n';break;} }if(flag)cout << "Yes" << '\n';}return 0;
}
组队竞赛
题目链接
题解
1. 排序 + 贪心
2. 总和最大 -> 每个小组的分数最大 -> 那么第二个人的分数尽可能大
3. 那就让第一个人最小,第三个人最大,第二个人次大
代码
#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;int main()
{int n; cin >> n;vector<int> ret(3*n);for(int i = 0;i < 3*n;i++) cin >> ret[i];sort(ret.begin(),ret.end());long long sum = 0;int count = n;for(int i = 3*n-2;i >= 0;i-=2){if(count == 0) break;sum += ret[i];count--;}cout << sum << '\n';return 0;
}
删除相邻数字的最大分数(线性dp)
题目链接
题解
1. 线性dp,可以转换为打家劫舍问题
2. 让hash表的下标为数组中的值,hash表中的数据对应所有相同的下标的数之和
3. 细节问题:可以让dp数组的长度为1e4 + 10,可以不用判断hash表中的最大的数为数组的长度,dp数组第0个值都初始化为0,因为原数组中没有0的值,返回选或者不选中dp数组的最大值,对应N-1下表中两个数组中的最大值
4. 为什么可以转换为打家劫舍问题?
因为数组中出现了相邻的数选或者不选,这个数选了下一个数就不能选
代码
#include <iostream>
#include<vector>
using namespace std;const int N = 1e4 + 10;
const int M = 1e5 + 10;
int ret[M];int main()
{int hash[N] = { 0 };int n = 0;cin >> n;for (int i = 0; i < n; i++) cin >> ret[i];for (int i = 0; i < n; i++){hash[ret[i]] += ret[i];}vector<int> f(N);// 选auto g = f;// 不选for (int i = 1; i < N; i++){f[i] = g[i - 1] + hash[i];g[i] = max(g[i - 1], f[i - 1]);}cout << max(f[N - 1], g[N - 1]) << '\n';return 0;
}