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(n2),我们再考虑优化使得时间复杂度降为O(n2):

我们再把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<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
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);
}

[Codeforces708E]Student's Camp的更多相关文章

  1. [CodeForces-708E]Student's Camp

    题目大意: 一个n*m的墙,被吹k天风,每块靠边的砖都有p的概率被吹掉. 如果上下两行没有直接相连的地方,我们则认为这一堵墙已经倒塌. 问最后墙不倒塌的概率(模意义). 思路: 动态规划. 用f[i] ...

  2. 【CF708E】Student's Camp 组合数+动态规划

    [CF708E]Student's Camp 题意:有一个n*m的网格,每一秒钟,所有左面没有格子的格子会有p的概率消失,右面没有格子的格子也会有p的概率消失,问你t秒钟后,整个网格的上边界和下边界仍 ...

  3. Student's Camp CodeForces - 708E (dp,前缀和优化)

    大意: $n$行$m$列砖, 白天左侧边界每块砖有$p$概率被摧毁, 晚上右侧边界有$p$概率被摧毁, 求最后上下边界连通的概率. 记${dp}_{i,l,r}$为遍历到第$t$行时, 第$t$行砖块 ...

  4. CF708E Student's Camp

    麻麻我会做*3100的计数了,我出息了 考虑朴素DP我们怎么做呢. 设\(f_{i,l,r}\)为第\(i\)层选择\(l,r\)的依旧不倒的概率. \(q(l,r)\)表示经历了\(k\)天后,存活 ...

  5. Codeforces 708E - Student's Camp(前缀和优化 dp)

    Codeforces 题目传送门 & 洛谷题目传送门 神仙 *3100,%%% 首先容易注意到 \(\forall i\in[1,m]\),第 \(i\) 行剩余的砖块一定构成一个区间,设其为 ...

  6. Codeforces Round #588 (Div. 2) D. Marcin and Training Camp(思维)

    链接: https://codeforces.com/contest/1230/problem/D 题意: Marcin is a coach in his university. There are ...

  7. java.io.NotSerializableException: test.io.file.Student

    java.io.NotSerializableException: test.io.file.Student    at java.io.ObjectOutputStream.writeObject0 ...

  8. 使用java反射机制编写Student类并保存

    定义Student类 package org; public class Student { private String _name = null; ; ; public Student() { } ...

  9. 参加MVP OpenDay 和2015 MVP Community Camp社区大课堂

    微软MVP Openday 1月30日在北京召开,到时全国上百位 MVP 专家将齐聚北京.当然还有亚太的其他国家地区的MVP 也会来北京,1月31日微软 MVP 项目组主办的年度微软技术社区分享大会- ...

随机推荐

  1. git分支错误提交导致代码丢失--窗口提示HEAD detached错误

    今天开发时git 检出分支到本地时操作错误,导致在一个临时分支上开发,且把代码提交了,结果代码未提交到任何分支,提交时还报了个错: HEAD detached at 4d927fa4 后来把代码重新检 ...

  2. 虚拟机镜像压缩(qcow2,raw)

    ●qcow2 格式的压缩首先,需要对虚拟机系统的剩余空间写零操作: $ dd if=/dev/zero of=/zero.dat 删除 zero.dat$ rm /zero.dat关闭虚拟机,进入虚拟 ...

  3. 微信小程序动态更改样式

    获取列表长度(动态渲染),当长度>x时添加内联样式并绑定数据{{}},通过js动态更改{{}}

  4. eslint简单的规范

    module.exports = { root: true, parser: 'babel-eslint', parserOptions: { sourceType: 'module' }, // h ...

  5. 第 3 章 镜像 - 013 - Dockerfile 构建镜像

    第一个 Dockerfile FROM ubuntu RUN apt-get update && apt-get install -y vim 运行 docker build 命令构建 ...

  6. 数据结构(C语言版)-第3章 栈和队列

    3.1 栈和队列的定义和特点3.2 案例引入3.3 栈的表示和操作的实现3.4 栈与递归3.5 队列的的表示和操作的实现3.6 案例分析与实现 基本操作有入栈.出栈.读栈顶元素值.建栈.判断栈满.栈空 ...

  7. 《HTTP 权威指南》笔记:第三章 HTTP 报文

    如果说 HTTP 是因特网的信使,那么 HTTP 报文就是它用来搬东西的包了. 这一章讲述关于 HTTP 报文的相关知识,包括: HTTP 报文的三个组成部分 请求报文以及其各种功能 响应报文以及各种 ...

  8. 并发之ThreadLocal

    ThreadLocal ThreadLocal 用一种存储变量与线程绑定的方式,在每个线程中用自己的 ThreadLocalMap 安全隔离变量,为解决多线程程序的并发问题提供了一种新的思路.   简 ...

  9. KM算法 带权二分匹配 O(n^3)

    #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #inclu ...

  10. CSS之transform-origin属性

    设置旋转元素的基点位置 语法 transform-orign:0 100% 0 transform-origin: x-axis y-axis z-axis; x-axis 定义视图被置于 X 轴的何 ...