难得这次题目都读完了
A
两个字符串,每次可以选相同长度颠倒顺序,看能不能一样
思路:第二个变偶数次相当于没变,只看第一个能不能变成第二个
字符串匹配+dp?
反正做不出来就对了
占坑
Hash(哈希),又称“散列”。
散列(hash)英文原意是“混杂”、“拼凑”、“重新表述”的意思。
在某种程度上,散列是与排序相反的一种操作,排序是将集合中的元素按照某种方式比如字典顺序排列在一起,而散列通过计算哈希值,打破元素之间原有的关系,使集合中的元素按照散列函数的分类进行排列。
在介绍一些集合时,我们总强调需要重写某个类的 equlas() 方法和 hashCode() 方法,确保唯一性。这里的 hashCode() 表示的是对当前对象的唯一标示。计算 hashCode 的过程就称作 哈希。
B
二进制串,可交换相邻元素,使字典序最少
把0一直往左移动就可以了
就是怕暴力会time out
等等再做
模拟+贪心
C
水题,贼爽
D
划分队伍,使最好的和最坏的差异最小
应该尽可能的队伍多,贪心
用结构体解决
刚刚发现,如果不是三的倍数,多出的一个小伙子不太好处理,可能要用dp?pass
结构体+dp
下周开始学dp吧,争取一个假期真正把dp学会
//官方题解,分析一下吧
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pt;
#define x first
#define y second
#define mp make_pair
const int N = 200043;
const int INF = int(1e9) + 43;
int n;
int dp[N];
int p[N];
pt a[N];
int t[N];
int main() {
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
a[i].y = i;//记下编号来干啥? --输出结果用
scanf("%d", &a[i].x);
}
sort(a, a + n);//根据成绩排序
for(int i = 1; i <= n; i++)
{
dp[i] = INF;
p[i] = -1;
}
//算区间dp?
for(int i = 0; i < n; i++)
for(int j = 3; j <= 5 && i + j <= n; j++)//6人一队跟两个三人完全一样
{
int diff = a[i + j - 1].x - a[i].x;
if(dp[i + j] > dp[i] + diff)//前几个是组好队的,后面组队方式不同
{
p[i + j] = i;//记录这个干啥? --答案输出最优的组队方式
dp[i + j] = dp[i] + diff;
}
}
int cur = n;
int cnt = 0;//记录队伍编号
while(cur != 0)
{
for(int i = cur - 1; i >= p[cur]; i--)
t[a[i].y] = cnt;
cnt++;
cur = p[cur];
}
printf("%d %d\n", dp[n], cnt);
for(int i = 0; i < n; i++)
{
if(i) printf(" ");
printf("%d", t[i] + 1);
}
puts("");
return 0;
}
dp真的太神奇了
E
贪心,相对较水,应注意细节
大致意思过河。铺板子
中间好麻烦
莫名其妙的bug
平常都是端点,这次来了个中间,恶心人;
以后多画图
一道普通的贪心,贪心策略也挺好找;不应该浪费这么多时间
F
交换连续的两个元素,使字典序最小
while (temp >= 1 && a[temp - 1] > a[temp] && vis[temp - 1] == 0) {
swap(a[temp - 1], a[temp]);
vis[temp - 1] = 1;temp--;//这个顺序搞错了,很无语,今天两次了
//cout << temp << " " << a[temp - 1] << " " << a[temp] << " " << vis[temp - 1] << endl;
无语了