0%

思路讲解

精髓在于猜这个你随机跳到其他位置以后,再跳到终点N+1的期望成本,可以设这个东西位S,用这个S算出来的S,我们叫做g(S)。那么 g(S)=Sg(S)=S 那是必须的,但是我们猜的不等于怎么办呢?

于是我们就二分。

至于这个二分的收敛方向嘛,我试着推了一下,我的建议是都试试。guess嘛。

image

这个图把y=x画的太斜了,实际上在y=x的下面,g(S)<Sg(S)<S,需要向左移动(也就是even<mid,r=mid)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 从x到N+1的最小期望成本
vdb dp(N+5);
DB l=0,r=accumulate(all(A),0ll)+accumulate(all(B),0ll);
FOR(_,1,100){
DB mid=(l+r)/2;
dp[N]=min((DB)A[N-1],mid+B[N-1]);
ROF(i,N-1,1){
dp[i]=min(dp[i+1]+A[i-1],mid+B[i-1]);
}
DB even=0;
FOR(i,1,N){
even+=dp[i];
}
// 包含位置 N+1 的 f=0(随机游走位置是包含N+1的)
even/=(N+1);
// 如果答案有问题,可以先换一下收敛方向
// 我们要尽可能的减少这个even与这个mid之间的差
if(even>mid){
l=mid;
}else{
r=mid;
}
}

AC代码

心路历程(WA,TLE,MLE……)

思路讲解

赛后自己想出来了

核心代码是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FOR(i,1,N){
if(cnt[i]==0) continue;
diff[cnt[i]+1]-=1;
diff[1]+=1;
}
// 这个sum维护的就是出现次数
// Sum[i] 表示出现次数大于等于i的数有Sum[i]个
vll Sum(N+5);
FOR(i,1,N){
Sum[i]=Sum[i-1]+diff[i];
}
ll ans=jichu;ll lans=jichu;
FOR(i,2,N){ // 枚举分为i条链的情况
if(Sum[i]<=1) break;
lans+=(Sum[i]-1)*X;
lans-=Sum[i]*Y;
lans+=Z;
ans=max(lans,ans);
}

AC代码

https://acm.hdu.edu.cn/contest/view-code?cid=1175&rid=12705

心路历程(WA,TLE,MLE……)

思路讲解(gemini翻译的题解)


首先,我们来解决一个简化版的问题,即假设数组 d 中全是 0(换句话-说,对于需要形成的排列 c 没有任何预设的限制)。

我们假设排列 a[1,2,3,4],排列 b[3,1,2,4]

假设我们已经选择了数组 c 的第一个元素为数组 a 的第一个元素(即 c[0] = a[0] = 1)。这样一来,我们就不能选择数组 b 的第一个元素了(b[0] = 3)。由于我们希望数组 c 是一个完整的排列,那么数字 3 就必须在 c 中出现,所以我们必须从数组 a 中找到 3 并将其加入到数组 c 中。

我们在数组 a 中寻找 3,发现它在索引 2 的位置(a[2]=3),于是我们选择 c[2] = a[2] = 3。这个选择导致我们不能再选择 b 中对应索引的元素(即 b[2]=2)。因此,我们又必须从 a 中找到 2 并加入 c。我们在 a 中找到 2 在索引 1 的位置(a[1]=2),所以选择 c[1] = a[1] = 2。这次,b 在该索引对应的元素是 1b[1]=1),而 1 已经因为我们最初的选择被包含在数组 c 中了。这样,我们就不再被强制要求从 a 中选择新的元素了,形成了一个闭环。

我们观察到,我们最初选择的元素 1,以及之后被“强制”选择的元素 23,即 [1,3,2](按选择顺序),与它们在 b 数组中对应位置的元素 [3,2,1] 构成了相同元素的排列。这些元素形成了一个“分组”。对于每个大小超过 1 的分组,我们都有 2 个选择:

  1. 将这个分组对应的所有元素都从 a 中选取。

  2. 将这个分组对应的所有元素都从 b 中选取。

所以,这个简化版问题的答案就是:找出所有这样相互关联的分组,统计其中大小超过 1 的分组数量(我们称之为 p),最终答案就是 2p。


那么,如果数组 d 不全是 0 该怎么办呢?

这种情况我们只需要在之前的逻辑上增加一个约束。对于我们找到的每一个分组,我们必须检查其所有成员在 d 数组中对应的位置是否全为 0

  • 如果一个分组对应的所有 d 数组位置上的值都是 0,那么这个分组就有两种选择(要么全选 a,要么全选 b),对最终答案的贡献是乘以 2

  • 如果一个分组中,哪怕只有一个成员在 d 数组中对应的位置不为 0(意味着这个位置的选择已经被 d 数组固定了),那么整个分组的选择也就被唯一确定了,它只有一种选择方案。这种分组对最终答案的贡献是乘以 1,我们就不需要把它计入 p 中。

这个解法可以通过多种方式实现,但在我看来,**使用并查集(Disjoint Set Union, DSU)**来将每个分组的元素合并在一起,是实现这个逻辑最优雅的方式。

AC代码

https://codeforces.com/contest/1670/submission/330958420

心路历程(WA,TLE,MLE……)