4

提交统计 # 标题
已解决 9 / 14 A Swapping Puzzle
已解决 11 / 16 B Prerequisites
已解决 11 / 20 C Family and Insurance
已解决 11 / 16 D Peaceful Teams
已解决 9 / 12 E Grid Ice Floor
已解决 7 / 20 F Cow Program
已解决 8 / 14 G Nastya and Potions
已解决 8 / 13 H Substring
已解决 9 / 32 I Tempter of the Bone
已解决 6 / 17 J Sequence one

4

闲话

有点遗憾 J 题没做出来,虽然我前两天一直在攻克我的剪枝问题,但好像做了好几天小木棍也没能提高我的剪枝能力,暂且记作遗憾吧。

A

继续返场。

然而突然想到 上一个题单 (突发恶疾 :3):

省流

最好写的题解:

看眼数据范围。...... ?直接大力艹过去就行。

看眼数据范围。\(2\le H,W \le 5\) ?直接大力艹过去就行。

B

?依赖问题?

看眼数据范围。\(2 \le N \le 2*10^5\) ?直接大力艹过去就行。

C

?传递?

看眼数据范围。\(2\le N,M \le 3*10^5\) ?直接大力艹过去就行。

啊呀坠机了!怎么回事?原来是我传递错了,要用 \(\max\) 不是 $sum $ 啊!

D

考虑大力……坠机了!时间复杂度是可恶的 \(O(N^T*(T+M))\) !我们要击败它,夺回我们飞机的控制权!

考虑记录枚举到的选手和队伍数,同时开一个数组记录哪个队伍里面有多少人。如果有还没有枚举到的选手数量小于还不存在选手的队伍数就直接叉掉。最后别忘了除以 \(T\) 的阶乘!

好耶!夺回来控制权了!可恶的 \(O(N^T*(T+M))\) ,你就直接无降落伞跳伞吧!别让我再看到你!

E

?看看有没有可恶的 \(O(N^T*(T+M))\) ?没有欸!

看眼数据范围。……?直接大力艹过去就行。记着加点润滑剂(小变化:要一直走到头)。

F

?不用看别起飞了,这就是纯恶心人的。考虑 记忆化搜索+剪枝 。如果当前状态之前访问过了,直接 -1 ,如果当前状态在上一个 \(a_1\) 的时候访问过了,直接把上一个的答案套过来。

不过有个更新奇的玩法,你可以直接建反图跑拓扑排序,也是很有情趣的做法呢 😛

G

看眼数据范围。\(2 \le K \le N \le 2*10^5\) ?直接大力艹过去就行。

H

有向图?任意大?环!Topo排序!直接设 \(F_{i,j}\) 为走到第 \(i\) 步时,字母 \(j\) 的最大出现次数!拓扑大力就行了。

I

?这个……直接DFS大力剪枝就过了。

J

没做。

但是后来做剪枝的时候补上了。有一个很奇怪的剪枝,是这样的:

bool check(int s,int e){
    for(int i=s+1;i<e;i++){
        if(a[i]==a[e])return 0;
    }
    return 1;
}

Gemini 这样给我解释的:

在解决 HDU2610 "Sequence one"(寻找长度为 \(L\) 的非递减子序列)时,你写的这段 check 函数是一个非常经典的 “同层去重”剪枝

简单来说,它的作用是:在当前搜索层级中,保证不选择数值完全相同的元素作为同一个位置的备选。


1. 为什么要这么做?(重复问题的来源)

假设原序列 \(a = \{1, 2, 2, 3\}\),你需要找长度为 2 的子序列。

  1. 第一种选法:选第一个 2,得到 \(\{1, 2\}\)
  2. 第二种选法:跳过第一个 2,选第二个 2,得到 \(\{1, 2\}\)

这两个 \(\{1, 2\}\) 是完全一样的。题目通常要求输出的是不同的子序列,如果你不剪枝,搜索树会把这两个序列都跑一遍,导致输出重复且效率低下。

2. 你的代码逻辑拆解

C++

bool check(int s, int e) {
    for(int i = s + 1; i < e; i++) {
        if(a[i] == a[e]) return 0; // 在范围内发现了和当前目标 a[e] 相同的数
    }
    return 1;
}
  • s:上一个选入序列的元素在原数组中的下标(如果是选第一个数,s 通常是 -1)。
  • e:当前正准备选入序列的元素下标。
  • 循环含义:它在检查从上一个位置到当前位置之间,是否已经出现过和 a[e] 相同的数值。
  • 返回值 0:如果 a[i] == a[e] 成立,说明在之前(i 处)已经尝试过用这个数值(例如数值 2)去填充当前这个坑位了。为了避免重复,现在就不再尝试 e 处的这个 2

不好理解的。但是是必要的。学一下总比不学强。

posted @ 2025-12-24 08:47  小林琴奈  阅读(2)  评论(0)    收藏  举报