删链表(概率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]
分两种情况讨论:
- 有2/n概率选到边节点,这时候剩下的节点就是n-2,所以此时操作次数的期望是(1+f(n-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:这是我一个学长面试的笔试题,没有链接