Flipping Coins

博客围绕扔硬币问题展开,有n个硬币初始正面朝下,需扔K次,每次选一个硬币。要使朝上硬币数期望最大,每次应选正面朝下的硬币。通过定义随机变量X,给出期望公式,总结扔硬币策略,还得出状态转移方程,最后递推概率求期望。

传送门

转自:https://www.cnblogs.com/LQLlulu/p/8886855.html(这篇博客写得真走心)

题意
有n个硬币排成一排,开始的时候所有的硬币都是正面朝下,你必须要扔K次硬币,每次选择一个硬币,问K次以后朝上的硬币数的最大期望是多少?

思路:期望值最大,则每次选择正面朝下的硬币仍

————————————————————————————————————————————————

随机变量X是指朝上的硬币数,当有N枚硬币的时候,X=0,1,2,3....N

E(X)=1*p(1)+2*p(2)+....+n*p(n)。

要想求最大期望,我们在扔硬币的时候要遵循一个策略:尽量扔正面朝下的硬币

如果当前有0到n-1枚硬币正面朝上,我们可以选择正面朝下的硬币来扔,扔完以后朝上硬币数不变或者+1

如果当前有n枚硬币正面朝上,我们只能选择正面朝上的硬币来扔,扔完以后朝上的硬币数不变或者-1

————————————————————————————————————————————————

令dp[i][j]为扔i次以后j枚硬币朝上的概率

根据上面总结的规律,我们可以的到状态转移方程

当j<n的时候

dp[i+1][j]+=dp[i][j]*0.5

dp[i+1][j+1]+=dp[i][j]*0.5

当j=n的时候

dp[i+1][j+1]+=dp[i][j]*0.5

dp[i+1][j-1]+=dp[i][j]*0.5

这样递推出概率来以后遍历一遍j求期望就好了~

代码如下:

#include <bits/stdc++.h>
#define pre(i,x,nn) for(int i=x;i<=nn;i++)
#define ll long long
using namespace std;
int n,k;
int main()
{
    scanf("%d%d",&n,&k);
    double dp[500][500]={0};
    dp[0][0]=1;
    for(int i=0;i<k;i++)
    {
       for(int j=0;j<=n;j++)
       {
           if(j<n)
           {
              dp[i+1][j]+=dp[i][j]/2.0;
              dp[i+1][j+1]+=dp[i][j]/2.0;
           }
           else
           {
               dp[i+1][j]+=dp[i][j]/2.0;
               dp[i+1][j-1]+=dp[i][j]/2.0;
           }
       }
    }
    double sum=0;
    pre(i,1,k)
      sum+=dp[k][i]*i;
    printf("%.10lf\n",sum);
    return 0;
}

 

### 关于翻转路径的算法 在图或树中,“翻转路径”的概念通常涉及改变节点之间的连接方向或者调整边的方向,使得某些特定条件得到满足。这种操作常见于有向无环图(DAG)、二叉树或其他类型的树形数据结构中的问题。 #### 图中的路径翻转 对于图中的路径翻转,可以考虑以下几种情况: - **反转子图中的所有边**:如果目标是从某个源节点到目标节点的路径被完全反转,则可以通过深度优先搜索(DFS)找到该路径并记录每条边的信息。随后逐一修改这些边的方向[^1]。 ```python def reverse_path_in_graph(graph, source, target): visited = set() path = [] def dfs(node): if node == target: return True visited.add(node) for neighbor in graph[node]: if neighbor not in visited: path.append((node, neighbor)) if dfs(neighbor): return True path.pop() # Backtrack return False if dfs(source): reversed_edges = [(v, u) for u, v in path] new_graph = {k: [] for k in graph} for u, v in reversed_edges: new_graph[u].append(v) return new_graph else: raise ValueError("No valid path found between {} and {}".format(source, target)) ``` 此代码片段展示了如何通过 DFS 找到一条从 `source` 到 `target` 的路径,并将其反转为新的图结构[^1]。 --- #### 树中的路径翻转 在树中,路径翻转可能意味着交换两个节点之间的一系列父子关系。例如,在一棵二叉树中,假设我们希望将根节点到某一叶子节点的路径上的所有左孩子变为右孩子,反之亦然: ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def flip_path_to_leaf(root, leaf_value): if not root: return None stack = [(root, [])] parent_map = {} while stack: current, ancestors = stack.pop() if current.val == leaf_value: break if current.left: parent_map[current.left] = (current, 'left') stack.append((current.left, ancestors + ['left'])) if current.right: parent_map[current.right] = (current, 'right') stack.append((current.right, ancestors + ['right'])) if current.val != leaf_value: return None # Leaf value not found prev_node = current for direction in reversed(ancestors): parent, side = parent_map[prev_node] if side == 'left': setattr(parent, 'right', getattr(parent, 'left')) delattr(parent, 'left') # Optional cleanup elif side == 'right': setattr(parent, 'left', getattr(parent, 'right')) delattr(parent, 'right') # Optional cleanup prev_node = parent return root ``` 这段代码实现了从根节点到指定叶节点路径的翻转逻辑。它利用栈来模拟递归过程,并动态更新父节点的孩子指针以完成路径翻转。 --- #### 应用场景扩展 除了基本的数据结构调整外,路径翻转还可以应用于更复杂的领域,比如医疗图像分析中的连通区域分割[^3] 或者自然语言处理中的依存句法树重排[^2]。具体实现取决于实际需求和输入数据的形式。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值