codeforces 722E. Research Rover

该博客详细解析了Codeforces 722E问题,研究如何在一个n*m的网格中,从起点(1,1)到终点(n,m),每次随机向右或向下移动,并考虑能量因异常网格减半的情况。博主通过分析能量变化,发现最多有20种可能的能量值,并采用动态规划方法计算每个能量值到达终点的方案数,最终求出到达终点时的期望能量值。文章给出了O(n^2*log(s))复杂度的解决方案。" 104668833,9133585,Linux文件操作详解:核心函数使用指南,"['Linux', '文件系统', '编程']
摘要由CSDN通过智能技术生成

题目链接http://codeforces.com/problemset/problem/722/E
题目大意:有一个n*m的网格,起点(1,1),终点(n,m),每次随机向右或向下走。一开始的能量为s,其中有k个网格异常,经过这样的网格会使能量从原来的x变为x/2的上取整(即(x+1)/2)。求最后到达(n,m)时的期望能量值。
数据范围:1 ≤ n, m ≤ 100 000, 0 ≤ k ≤ 2000, 1 ≤ s ≤ 1 000 000

题解:由于s每次遇到异常的网格都减半,最多减logs次就变成1,这样能量值最多有20种,所以我们只需要统计走到终点时每种能量值的方案数即可。
首先将点的坐标以x为第一关键字,y为第二关键字排序,然后在最前面添一个点(1,1)(即第0个点),从后往前进行dp(由于一开始想叉了写了从后往前的dp,这里也就依照代码进行分析,事实上从前往后也一样。)
为了方便,令d[i][j]表示从点 i 走到点 j 的方案数,即d[i][j]=C(p[j].x-p[i].x+p[j].y-p[i].y,p[j].x-p[i].x)。
设g[i][j]表示从点(n,m)走到第 i 个点,途中恰好经过了 j 个异常点(不包括点 i )的方案数。直接求g不太好求,那么我们再设f[i][j]表示经过了不超过j个点的方案数,这样只要在总方案数中减去超过了 j 个点的方案数即可。所以我们枚举经过的第 j 个异常点,则f[i][j]=d[i][(n,m)]-∑(g[l][j]*d[i][l]),g[i][j]=f[i][j]-f[i][j-1],其中p[i].x<=p[l].x且p[i].y<=p[l].y。
计算出所有的方案数之后,最后答案为(∑g[0][i]*a[i])/d[(1,1)][(n,m)],a[i]表示经过 i 个异常点后s的值。
时间复杂度O(n^2logs)

代码如下:

#include <algorithm>
#include <cstdio>
using namespace std;
const int mo=1000000007;
int a[30],fac[200005],ine[200005],g[20
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值