zoukankan      html  css  js  c++  java
  • [Codeforces708E]Student's Camp

    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
    ", (sumr[n][m] + mo) % mo);
    }
    
  • 相关阅读:
    c#整除
    CR尼尔森相关人士曾表示,Facebook是美国校园社团文化的在线延续,但在中国并不具备这样的环境。社区用户群的年轻化以及浓郁的乡情或地域情节使得国内社区网站更趋向于同城交友平台,而并不是个人社交圈的扩展。
    Java / 第8章 类的基础知识
    汇编/ 第一章: 基础知识(甲)
    天若有情天易老 人间正道是沧桑
    Java/1 7章
    产品经理之竞品分析下
    产品经理之产品竞品上
    产品经理之产品调研
    Java数据类型
  • 原文地址:https://www.cnblogs.com/WizardCowboy/p/7685535.html
Copyright © 2011-2022 走看看