博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Codeforces708E]Student's Camp
阅读量:5946 次
发布时间:2019-06-19

本文共 2762 字,大约阅读时间需要 9 分钟。

Problem

一个n*m块砖的建筑,一共k天,每天风从两边吹,吹掉砖的概率为p,反之为1-p,求最终建筑没有倒塌的可能性(上层与下层有交集且每一层都有砖)

Solution

首先,我们可以预处理出pl[]和pr[]数组,表示k天后左右两边风吹到的位置的可能性

然后我们可以枚举层数,当前这一层的左右端点和上一层的左右端点,如果有公共部分则转移
这样的时间复杂度是O(n^5),显然我们可以用前缀和来优化:
引入f[i][r]+=dp[i][l][r](l <= r),再用一个sumr数组维护f数组的前缀和(suml数组是和sumr对称的)
那么dp[i][l][r]就等于总概率减去上一层区间在这个区间左边的概率和上一层区间在这个区间右边的概率(不相交的概率)
这样时间复杂度就降为了O(n^2),我们再考虑优化使得时间复杂度降为O(n^2):
我们再把dp降为两维,表示第i层最右边是j的概率
dp[i][j]=pl[l]pr[r](sumr[i-1][m] - suml[i-1][r+1] - sumr[i-1][l-1])
我们发现当l改变时,dp[i][j]改变的是可以再用前缀和维护的
于是时间复杂度变成了O(n^2)

Notice

前缀和预处理较多

Code

#include
#include
#include
#include
#include
using namespace std;#define sqz main#define ll long long#define reg register int#define rep(i, a, b) for (reg i = a; i <= b; i++)#define per(i, a, b) for (reg i = a; i >= b; i--)#define travel(i, u) for (reg i = head[u]; i; i = edge[i].next)const int INF = 1e9, mo = INF + 7, N = 1505, K = 100005;const double eps = 1e-6, phi = acos(-1.0);ll mod(ll a, ll b) {if (a >= b || a < 0) a %= b; if (a < 0) a += b; return a;}ll read(){ ll x = 0; int zf = 1; char ch; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;}void write(ll y) { if (y < 0) putchar('-'), y = -y; if (y > 9) write(y / 10); putchar(y % 10 + '0');}ll p1[K], p2[K];ll dp[N][N], suml[N][N], sumr[N][N], sum1[N], sum2[N], tt[K], pl[N], pr[N];ll quickmo(ll x, int y){ ll ans = 1; while (y) { if (y & 1) ans = ans * x % mo; x = x * x % mo; y /= 2; } return ans;}ll C(int n, int m){ return tt[m] * quickmo(tt[m - n], mo - 2) % mo * quickmo(tt[n], mo - 2) % mo;}int sqz(){ int n = read(), m = read(); ll a = read(), b = read(); int k = read(); p1[0] = 1, p1[1] = a * quickmo(b, mo - 2) % mo; p2[0] = 1, p2[1] = (b - a) * quickmo(b, mo - 2) % mo; rep(i, 2, k) p1[i] = p1[i - 1] * p1[1] % mo, p2[i] = p2[i - 1] * p2[1] % mo; tt[0] = 1; rep(i, 1, k) tt[i] = tt[i - 1] * i % mo; rep(i, 0, m - 1) { if (i > k) pl[i + 1] = 0; else pl[i + 1] = C(i, k) * p1[i] % mo * p2[k - i] % mo; pr[m - i] = pl[i + 1]; } rep(i, 1, m) sum1[i] = (sum1[i - 1] + pl[i]) % mo; sumr[0][m] = 1; rep(i, 1, n) { rep(j, 1, m) sum2[j] = (sum2[j - 1] + pl[j] * sumr[i - 1][j - 1]) % mo; rep(j, 1, m) dp[i][j] = (pr[j] * (sumr[i - 1][m] - suml[i - 1][j + 1]) % mo * sum1[j] % mo - pr[j] * sum2[j] % mo + mo) % mo; rep(j, 1, m) suml[i][m - j + 1] = sumr[i][j] = (sumr[i][j - 1] + dp[i][j]) % mo; } printf("%lld\n", (sumr[n][m] + mo) % mo);}

转载于:https://www.cnblogs.com/WizardCowboy/p/7685535.html

你可能感兴趣的文章
常用的脚本编程知识点
查看>>
计算机网络术语总结4
查看>>
新手小白 python之路 Day3 (string 常用方法)
查看>>
soapUI的简单使用(webservice接口功能测试)
查看>>
框架 Hibernate
查看>>
python-while循环
查看>>
手机端上传图片及java后台接收和ajaxForm提交
查看>>
【MSDN 目录】C#编程指南、C#教程、ASP.NET参考、ASP.NET 4、.NET Framework类库
查看>>
jquery 怎么触发select的change事件
查看>>
angularjs指令(二)
查看>>
<气场>读书笔记
查看>>
领域驱动设计,构建简单的新闻系统,20分钟够吗?
查看>>
web安全问题分析与防御总结
查看>>
React 组件通信之 React context
查看>>
Linux下通过配置Crontab实现进程守护
查看>>
ios 打包上传Appstore 时报的错误 90101 90149
查看>>
Oracle推出轻量级Java微服务框架Helidon
查看>>
密码概述
查看>>
jQuery的技巧01
查看>>
基于泛型实现的ibatis通用分页查询
查看>>