2022.10.11 闲话

闲话闲的没事就更一下,本来想多停更几天的 TAT

最近一直在想一个 Galgame つい・ゆり 〜おかあさんにはナイショだよ〜 /youl

Rolling_star 推的歌词:

逃避行

さよなら 逃避行
昨日の酔いも 覚めない君と
抜け出す街を 行こう
背負い込んだ重い過去も
飲み込んだ思いすらも
乗り越えた 乗り越えた 二人で
錆びついたこの心も
夢を見たあの気持ちと
飛び込んだ 飛び込んだ 二人で
さよなら 逃避行
昨日の酔いも 覚めない君と
抜け出す街を 行こう
さよなら 逃避行
「夢を見たいの」
泣き出す君と 抜け出す街を
行こう 行こう 行こう
大それたものじゃないの
泣いていたこの思いも
ただそれは
ただそれは
蓋をしたの 誰の声も
聞こえぬほど 君も溺れてく
夢を見たの 戻れないの
さよなら 逃避行
「君と居たいよ」
褪せない 日々と
抜け出す街を 行こう
さよなら 逃避行
「明日を見たいの」
先立つ 君と 抜け出す街を
行こう 行こう 行こう

未限定容量的 01 背包

全文集合均为可重集 .

题目描述

接力游戏

两个集合 \(S_1,S_2\),第 \(i\) 个集合由 \(n_i\) 个二元组 \((v_{i,j},w_{i,j})\) 组成,取 \(S_1,S_2\) 的子集 \(s_1,s_2\),使得 \(\displaystyle \sum_{(v_i,w_i)\in s_1}w_i=\displaystyle \sum_{(v_i,w_i)\in s_2}w_i\) .

问所有选取方案中,\(\displaystyle \operatorname{value}(s_1,s_2)=\sum_{(v_i,w_i)\in (s_1\cup s_2)}v_i\) 最大的是什么,只需输出最大的 \(\operatorname{value}(s_1,s_2)\) .

\(1\le |S_1|,|S_2|,w_i\le 10^3\) ,\(|v_i|\le 10^9\) .

对于 \(S_2\) 中的所有元素,令 \(w_i\gets -w_i\),则问题变成从一个集合 \(S=S_1\cup S_2\) 中选一个子集 \(s\subseteq S\),使得 \(\displaystyle\sum_{(v_i,w_i)\in s}w_i=0\)\(\displaystyle\sum_{(v_i,w_i)\in s}v_i\) 最大 .

这是一个 01 背包,只不过没有容量限制 .

\(\displaystyle V = \sum_{(v_i,w_i)\in S}w_i=0\),则直接跑 01 背包的时间复杂度是 \(\Theta(nV)\) 的,必然是过不去的 .

那么如何做呢?有些人采用一个邪教做法:

做法 1

\(S\)\(w_i\) 排序,构成序列 \(\{v_n\},\{w_n\}\) .

\(dp_{i,j}\) 表示前 \(i\) 个物品容量为 \(j\) 的答案,则 \(j\) 的上界为 \(\displaystyle\sum_{k=1}^iw_k\) .

那么以 \(\displaystyle\sum_{k=1}^iw_k\) 为容量跑 01 背包即可 .

其实用时的量级就是 \(\displaystyle\sum_{i=1}^n\sum_{j=1}^iw_i\),所以实际上时间复杂度还是 \(\Theta(nV)\) .

我们精细分析一下,复杂度卡满的情况显然就是 \(|S_1|=|S_2|=w_i=10^3\)(注意这时 \(n=|S_1\cup S_2|=2\times 10^3\)),这时基本运行次数为

\[\sum_{i=1}^{2\times 10^3}\sum_{j=1}^i2\times10^3=2\times 10^3\cdot\dfrac{2\times 10^3\cdot(2\times 10^3+1)}{2}=4.002\times 10^9 \]

这样 1s 必然是跑不过去的 .

然而我们可以分两次,用两个 DP,分别跑 \(dp_{0/1,i,j}\) 表示 \(S_1\)\(S_2\) 集合内前 \(i\) 个跑到容量 \(j\) 的答案,那么两个 DP 分别用上面的方法做,这时基本运行次数为

\[2\times\sum_{i=1}^{10^3}\sum_{j=1}^i10^3=10^3\times10^3\times(10^3+1)=1.001\times 10^9 \]

感觉优化也只能优化为 \(9.99\times 10^8\) 啊,怎么可能过得去呢?可能 -O2 力量非凡吧……

好吧我们假设出题人的数据是随的,即 \(n=10^3\)\(w_i\)\([1,10^3]\) 中均匀随机 .

则两次 DP 的期望运行次数(的一个上界)为

\[2\sum_{i=1}^{10^3}2i\times 10^2=2.002\times 10^8 \]

额,好像能过吧 /yun

做法 2

随机打乱原集合,然后 DP 时设阈值 \(L\),过程中舍弃容量的绝对值 \(\ge L\) 的状态 .

这样的时间复杂度为 \(\Theta(nL)\)\(L\)\(5\times 10^4\) 左右就可以通过了 .

关于分析啥的,不想写了 .

这篇闲话是不是有点水啊……打算有朝一日写一个最大子段和的闲话 .

posted @ 2022-10-11 17:52  Jijidawang  阅读(90)  评论(2编辑  收藏  举报
😅​