Noi2017 泳池

Posted weiyanpeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Noi2017 泳池相关的知识,希望对你有一定的参考价值。

首先考虑dp。

不难发现我们大概是对于每一个高度不能有连续的一段长度,并且在下面都安全的时候才计入限制。

\(f[i][j]\)表示长度为i的泳池从高度j开始(i,j)的矩形默认安全,满足最大矩形小于k的概率.

转移相当于做一个类似背包的东西。

然后发现\(j>0\)的时候\(i\le 1000\)(否则dp值为0),然后因为要枚举上一层选择了多少,这个最多到1000。

则,枚举上一个0的位置

\[ f[i][0]=\sum f[j][0] * (f[i-j-1][1] * p^i-j-1*(1-p)) \]
线性递推就没了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
inline int add(int a,int b)a+=b;return a>=mod?a-mod:a;
inline int sub(int a,int b)a-=b;return a<0?a+mod:a;
inline int mul(int a,int b)return (ll)a*b%mod;
inline int qpow(int a,int b)
    int ret=1;for(;b;b>>=1,a=mul(a,a))if(b&1)ret=mul(ret,a);return ret;
inline int _inv(int x)return qpow(x,mod-2);
/* math */

int n,k,x,y,p;
const int N=1e3+6;
int f[N][N];
typedef vector<int> poly;
poly F,A,R;

poly mul(poly a,poly b)
    poly ret(a.size()+b.size()-1,0);
    for(size_t i=0;i<a.size();i++)for(size_t j=0;j<b.size();j++)ret[i+j]=add(ret[i+j],mul(a[i],b[j]));
    return ret;

poly Div(poly a,poly b)
    int t=b[b.size()-1];
    t=_inv(t);
    for(size_t i=a.size()-1;i>=b.size()-1;i--)
        int temp=mul(a[i],t);
        for(size_t pos=i,j=b.size()-1;~j;pos--,j--)
            a[pos]=sub(a[pos],mul(temp,b[j]));
        
    
    a.resize(min(a.size(),b.size()-1));
    return a;


inline int solve(int k)
    memset(f,0,sizeof(f));
    for(int j=0;j<=k+2;j++)f[0][j]=1;
    for(int i=1;i<=k;i++)for(int j=k/i;~j;j--)
        f[i][j]=mul(qpow(p,i),f[i][j+1]);
        for(int k=1,P=sub(1,p);k<=i;k++,P=mul(P,p))
            f[i][j]=add(mul(f[k-1][j+1],mul(P,f[i-k][j])),f[i][j]);
        
    
    F.resize(k+2);
    for(int i=0;i<=k;i++)F[i]=mul(mul(sub(p,1),qpow(p,k-i)),f[k-i][1]);
    F[k+1]=1;
    A=poly(2,0);A[1]=1;
    R=poly(1,1);
    int K=n;
    for(;K;K>>=1)
        if(K&1)
            R=mul(R,A);
            R=Div(R,F);
        
        A=mul(A,A);
        A=Div(A,F);
    
    int ret=0;
    for(size_t i=0;i<R.size();i++)
        ret=add(ret,mul(R[i],f[i][0]));
    
    return ret;


int main()

    cin >> n >> k >> x >> y;p=mul(x,_inv(y));
    printf("%d\n",sub(solve(k),solve(k-1)));

以上是关于Noi2017 泳池的主要内容,如果未能解决你的问题,请参考以下文章

uoj316NOI2017泳池

[NOI2017]游戏

NOI2017 [NOI2017]游戏 2-sat

Cocoa beach 海滩 299.5万 5房5浴海滨豪华别墅 私人泳池/海灘/面海景

大揭秘:游泳池防水材料,泳池胶膜

NOI2017 划水记