【LGR-119】洛谷 9 月月赛 I & Wdoi2022 R2 Div.2 过程
前言
还是太菜了,只拿了 235pts.
正文
T1
脑子没坏就能想出来。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rint register int
int N;
int a[500005], b[500005];
signed main()
{
cin >> N;
for(int i = 1; i <= N; ++ i)
scanf("%d", &a[i]);
for(int i = 1; i <= N; ++ i)
scanf("%d", &b[i]);
int cnt1, cnt2;
cnt1 = 0, cnt2 = 1;
for(int i = 1; i <= N; ++ i)
if(a[i] != b[i]) ++ cnt1;
for(int i = 1; i <= N; ++ i)
if(a[N - i + 1] != b[i]) ++ cnt2;
cout << min(cnt1, cnt2) << endl;
return 0;
}
T2
这道题真的有点难想啊,一开始以为是线段树。
就是一道十分纯良的 DP 辣。 设 \(pre_i\) 为正着考虑到第 \(i\) 个的独立集大小。
那么显然答案要从 \(a_i \ne 3\) 的人转移,所以尝试暴力枚举每一个人。注意这样复杂度 \(\mathcal{O}(N^2)\), 无法通过。
由于该题不像单调队列优化那样有一个只能选前 \(k\) 个数进行转移的范围限制,那么考虑直接使用前缀最大值优化。
观察性质发现 \(a_i = 3\) 无法用于转移,而 \(a_i = 2\) 无法转移自前面的人,于是只可取 \(a_i = 1\) 者计算前缀最大值。
那么再来考虑前缀最大的初始值。发现 \(a_1 = 3\) 时前缀最大初始值为 \(0\), 否则为 \(1\).
这样就做完啦。不过还要反着搞一遍,转移条件就稍微改一下就行。具体见代码。
#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long
#define rint register int
ll N, ans;
ll arr[1000005], pre[1000005], suf[1000005];
signed main()
{
cin >> N;
for(int i = 1; i <= N; ++ i)
scanf("%lld", &arr[i]);
if(N == 1)
puts("1"), exit(0);
ll premax = 0;
if(arr[1] != 3) ++ premax;
pre[1] = 1;
for(int i = 2; i <= N; ++ i)
{
pre[i] = 1;
if(arr[i] == 2) continue;
pre[i] = max(pre[i], premax + 1);
if(arr[i] == 1) premax = max(premax, pre[i]);
}
ll sufmax = 0;
if(arr[N] != 2) ++ sufmax;
suf[N] = 1;
for(int i = N - 1; i >= 1; -- i)
{
suf[i] = 1;
if(arr[i] == 3) continue;
suf[i] = max(suf[i], sufmax + 1);
if(arr[i] == 1) sufmax = max(sufmax, suf[i]);
}
for(int i = 1; i <= N; ++ i)
ans = max(ans, max(pre[i], suf[i]));
cout << ans << endl;
return 0;
}
这题我竟然写了 1.5h, 太浪费时间了 QAQ...
T3
T4
WA 有情应识我,日日相见在机房。
四个暴力拿省一,两个标算也不行。
本文来自博客园。 作者: JackMerryYoung, 转载请注明原文链接: https://www.cnblogs.com/JackMerryYoung/p/16678018.html
兴罢了,今天就写到这吧。何时才能为所欲为?!