edu153

edu 153

总评:做得很差,肯本没有认真思考

A

可以发现输出的串要么是 \(()()()...\) 要么是 \((((((...)))))\)

我们只需要判断给定串是否是 \(()()()()...\) 即可,如果是,就输出第二种方案,否则输出第一种

做的极慢的原因:还真说不出来,可能是分类讨论做少了,没有任何的经验

Code

B

上来想到贪心,样例三发现贪心不对

发现在给定的 \(ak\)\(a1\) 和特殊硬币做文章非常难搞,于是想到直接不管价值,直接算需要的 \(k\) 硬币和 \(1\) 硬币的数量(设 \(k\) 硬币的数量为 \(ned_k\)\(1\) 硬币的数量同理),用需要的数量减去给定的数量,就是剩下的特殊币的数量,但是发现 \(a1\) 此时可能有剩余,贪心的把他换成特殊币的 \(k\) 的数量即可

看了很多大佬的想法,都是一样的

但是代码实现不同,可以直接如上暴力模拟:Code

当然还有一种更妙的实现方式,直接求出来最终答案的 \(k\) 的数量

\(k\) 的大小有两种可能

  1. 直接用 \(\frac{m}{k}\)
  2. 可以先把 \(a1\) 尽量用上,然后在用 \(k\) ,即 \(\frac{m-a1}{k}\) 但是这里记得要上取整,如果 \(a1\) 不能填满一个 \(k\) ,那么还是需要一个 \(k\) 来填上

代码:Code

花了半个小时的原因:在 pass 掉贪心后,没有快速想到直接算 \(k\) 硬币

C

这题我看了一眼就会了,但是少考虑的一个点,导致 \(20min\) 没打完,遗憾离场

首先看到是博弈,需要确定必胜态和必败态,发现必败态是好找的,当前这个点是必败态当且仅当这个点之前没有比他小的数

注意到如果一个点是必胜态,当且仅当以这个点结尾的最长上升子序列长度为 \(2\) ,这样 \(Bob\) 只能选择前面的一个点,那么 \(Alice\) 获胜。否则,如果长度 \(\ge 3\) 那么 \(Bob\) 可以跳到长度为 \(2\) 的上,那么 \(Alice\) 必败

因此,我们直接用树状数组维护即可

Code

去读大佬的代码,发现有如上性质以后,可以做到 \(O(n)\)

我们其实只用记录两个东西,以某个点结尾的最长上升子序列的长度分别是 \(1\)\(2\)

Code

没有分析到的是 长度 \(\ge3\) 所以导致短短的代码 \(20min\) 没写出来/oh

D

这个 \(dp\) 怎么看到我这么晕啊/oh dp 真的需要练练了/cf

看题意觉得不是很好做,所以想到了 dp /oh 一般不会转化的题就用 dp /cf

首先收集信息,按照常理需要一个 \(i\) 表示在第几位,\(j\) 表示前面有几个 \(1\) ,但发现想要转移并统计答案完全不够

思考下题目的性质,最后其实是想让 \(01\) 的个数减去 \(10\) 的个数等于 \(0\),进一步转化,对于每一个 \(1\)\(1\) 前面 \(0\) 的数量减去后面 \(0\) 的数量最后求和等于 \(0\) ,这样第三维就可以设置成,前 \(i\) 个数的贡献的值

发现第三维有点小问题,因为他有可能为负数,所以我们要思考一下最小可能是多少,发现最小是前面全是 \(1\) ,后面全是 \(0\) 的时候,答案为 \(-\frac{n*n}{4}\) ,所以第三维提前加上 \(\frac{n*n}{4}\) ,这样的话就能保证下标不是 \(0\)

最后思考下 \(dp\) 转移:(假设 \(cnt0\)\(0\) 在数组中总共出现的次数,\(cnt1\)\(1\) 出现的次数)

  1. 当前位为 \(0\) ,转移为 \(dp[i][j][k]=dp[i-1][j][k]+a[i]\)
  2. 当前位为 \(1\) ,转移为 \(dp[i][j][k]=min(dp[i][j][k],dp[i-1][j-1][k+2*(i-j)-cnt0]+!a[i]\)

第二个转移也就是加入一个 \(1\) ,前面的 \(0\) 的个数为 \((i-j)\) ,后面 \(0\) 的个数为 \(cnt0-(i-j)\) 所以前面前后面为 \(2*(i-j)-cnt0\)

最后的答案为 \(dp[cnt1][0]/2\) 因为记录答案的时候交换 \(1\) 记录了一次,交换 \(0\) 也记录了一次,所以直接 \(/2\) 即可

Code

F

发现 \(F\) 是个非常简单的题目

要求最小操作次数,而且行动的方式也有了,大概率会想到最短路

向左和向右的连边是 \(O(n)\) 的,但是发现第三种操作是麻烦的,会有 \(O(n^2)\) 条边,所以可以轻松想到要去优化建图,仔细观察 \(C\) 操作,可以发现一个地方移动到另一个地方需要经过 \(xy\) 这样类似的两个字母(必须相同),可以想到对于每个 \(xy\) 建一个虚点,然后让每个这样的字符集连向这个虚点,这个时候发现边的个数变成了 \(O(n)\) 的。

接着思考怎么每条边的边权如何,左右边直接赋值为 \(1\) ,但是虚点的两条边只能有 \(1\) 的权值,用 \(0.5\) 昨晚边权大概可以,但发现不需要,可以向虚点连一条权值为 \(1\) 的边,然后让虚点让对应的点连一条权值为 \(0\) 的边即可

然后发现直接求 \(dis[x][y]\) 的复杂度还是 \(n^2\) 的,但是我们可以钦定某个点必须经过,然后取一个最小值即可

那么对于 \(26*26\) 个点分别跑一次 \(01bfs\) 就可以了,复杂度差不多是 \(26*26*n\)

这道题一共需要三个重要的点:1. 先优化建图 2. 边权的设置 3. 如果求答案

其实还有一个很坑的地方,就是 \(vis\) 数组可能会炸掉,所以用 bitset 来节约一下空间

Code

posted @ 2023-09-01 10:46  taozhiming  阅读(23)  评论(0)    收藏  举报