删链表(概率dp)

小红拿到了一个链表。她每次操作会随机选择一个节点,将该节点、该节点下个节点和该节点上一个节点同时删除。请注意,如果选择的节点是头节点,则不存在上一个节点;若是尾节点,则不存在下一个节点。小红希望你计算将链表删成空链表的操作次数的期望。

\[1<=n<= 10^5 \]

如果你返回的答案和正确答案的相对误差不超过\(10^{-3}\),则认为你的答案正确。

示例1
输入输出示例仅供调试,后台判题数据一般不包含示
输入
3
输出
1.66666667

这个题很明显是一个概率dp:
他的状态转移方程式
dp[i]=2/i*dp[i-2]+(i-2)/i*dp[i-3]
分两种情况讨论:

  1. 有2/n概率选到边节点,这时候剩下的节点就是n-2,所以此时操作次数的期望是(1+f(n-2)的期望操作数)
  2. 有(n-2)/n的概率选择列表中间,此时操作此时的期望是(1+f(n-3)的期望操作数)
    1是当前操作的次数,所以要+1,+1表示的是状态转移时发生的这次操作
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+100;
double dp[maxn];
int main(){
	dp[1]=1.0;
	dp[2]=1.0;
	dp[3]=5.0/3.0;
	for(int i=4;i<=n;i++){
		dp[i]=2.0/(1.0*i)*dp[i-2]+(i-2)*(1.0)/(i*1.0)*(dp[i-3]);
	}
	printf("%lf\n",dp[n]);
	return 0;
} 

ps:这是我一个学长面试的笔试题,没有链接

posted @ 2023-11-06 10:42  lipu123  阅读(85)  评论(0)    收藏  举报