LOJ 2304 "NOI2017" pool - ideas + DP + constant coefficient linear homogeneous recurrence

 

Topic: https://loj.ac/problem/2304

Read a variety of explanations ......

\ (DP [i] [j] \) represents the i-row, j-th row and the following default method, a j + 1-row illegal probability that at least a grid, a rectangular area to meet the maximum legal <= lm. Where the j-th row and the following contribution is part of q 1 instead of several parties.

那么有 \( dp[i][j]=dp[i][j+1]*p^i + \sum\limits_{k=1}^{i}dp[k-1][j+1]*p^{k-1}*(1-p)*dp[i-k][j] \)

Note that when i> k, when the bottom line must have at least one position is illegal. So order \ (ans_i \) represents the probability of i th column with \ (ans_i = \ sum \ limits_ {j = 1} ^ {i} ans_ {j-1} * (1-p) * dp [ij] [1 ] * p ^ {ij} \)

\ (Ans_i \) is the initial value of dp [i] [0]. Note dp [0] [*] = 1. You can then use constant coefficient linear homogeneous recurrence of knowledge optimization.

Note empty array. Do not pay attention to the value of n really get rid of.

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1005,M=N<<1,mod=998244353;
int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;}
int pw(int x,int k)
{int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;}

int n,q,q2,f[N][N],bin[N],a[N],ans[M],b[M],c[M],lm;
void Mul(int *u,int *v)//(lm-1)'
{
  memset(c,0,sizeof c);
  for(int i=0;i<lm;i++)
    for(int j=0;j<lm;j++)
      c[i+j]=(c[i+j]+(ll)u[i]*v[j])%mod;

  for(int i=2*(lm-1);i>=lm;i--)
    if(c[i])
      for(int j=1;j<=lm;j++)
    c[i-j]=(c[i-j]+(ll)c[i]*a[j])%mod;
  memcpy(u,c,sizeof 4*lm);//0~lm-1
}
int solve(int tmp)
{
  lm=tmp; memset(f,0,sizeof f);
  for(int j=0;j<=lm+1;j++)f[0][j]=1;//lm+1 not lm!!!
  for(int i=1;i<=lm;i++)
    for(int j=lm/i;j>=0;j--)
      {
    int tp=(ll)f[i][j+1]*bin[i]%mod;
    for(int k=1;k<=i;k++)
      {
        int ml=(ll)f[k-1][j+1]*f[i-k][j]%mod;
        ml=(ll)ml*q2%mod*bin[k-1]%mod;
        tp=upt(tp+ml);
      }
    f[i][j]=tp;
      }
  if(n<=lm)return f[n][0]; lm++;

  for(int i=1;i<=lm;i++)
    {
      int tp=(ll)f[i-1][1]*bin[i-1]%mod;
      a[i]=(ll)tp*q2%mod;//not lm-i
    }
  memset(ans,0,sizeof ans);////
  memset(b,0,sizeof b);////
  ans[0]=b[1]=1; int tn=n;//////
  while(tn)
    {
      if(tn&1)Mul(ans,b); Mul(b,b); tn>>=1;
    }
  int ret=0;
  for(int i=0;i<lm;i++)
    ret=(ret+(ll)ans[i]*f[i][0])%mod;
  return ret;
}
int main()
{
  int x,y,k;scanf("%d%d%d%d",&n,&k,&x,&y);
  q=(ll)x*pw(y,mod-2)%mod; q2=upt(1-q);
  bin[0]=1;
  for(int i=1;i<=k;i++)bin[i]=(ll)bin[i-1]*q%mod;
  printf("%d\n",upt(solve(k)-solve(k-1)));
  return 0;
}

 

Guess you like

Origin www.cnblogs.com/Narh/p/10993097.html