D. Jon and Orbs (probability dp, 2200)

Topic portal

Question: There are k kinds of balls, one kind of ball is randomly generated with equal probability every day, and it is collected. For q times of inquiries, ask one p each time, and ask you how many days at least, the probability that you have collected all k balls is greater than or equal to p 2000 \frac {p}{2000}2000p 。( k , q , p < = 1000 k,q,p<=1000 k,q,p<=1000

Idea: Let's set f [i] [j] f[i][j]F [ I ] [ J ]为前iicollectedjj in i daysThe probability of j breeding eggs, thenf [i] [j] f[i][j]f [ i ] [ j ] There are two ways to transfer:

  1. [ i ≥ j ] : f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] + ( k − j + 1 ) / k [i≥j]:f[i][j]=f[i-1][j-1]+(k-j+1)/k [ij]:f[i][j]=f[i1][j1]+(kj+1)/k
  2. [ i − 1 ≥ j ] : f [ i ] [ j ] = f [ i − 1 ] [ j ] + j / k [i-1≥j]:f[i][j]=f[i-1][j]+j/k [i1j]:f[i][j]=f[i1][j]+j/k

Because f [i] [j] f[i][j]f [ i ] [ j ] givenf [i − 1] [j] f [i-1] [j]f[i1][j] f [ i − 1 ] [ j − 1 ] f[i-1][j-1] f[i1][j1 ] Relevant, that is, it is only related to the upper layer, so we can consider rolling the array to optimize one dimension. (Although forcibly opening two dimensions can also be passed, but the optimized space-time performance is significantly better than before optimization)

We use ans[i] to represent the minimum number of days required when p=i. Because ppThe maximum p is 1000, so when we finish processing ans[1000], we can exit the preprocessing.

Code:

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define lowbit(x) x&-x
#define pii pair<int,int>
#define ull unsigned long long
#define pdd pair<double,double>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
    
    
    int x=0,f=1;
    char ch=gc();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')
            f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
using namespace std;
const int N=3e6+666;
const int inf=0x3f3f3f3f;
const int mod=998244353;
const double eps=1e-7;
const double PI=acos(-1);

double f[11111];
int ans[N],cnt=0;

signed main()
{
    
    
    int k,q;
    cin>>k>>q;
    f[0]=1;
    for(int i=1;cnt<=1000;i++)
    {
    
    
        for(int j=min(i,k);j>=1;j--)
            f[j]=(f[j-1]*(k-(j-1))+f[j]*j)/k;
        while(i>=k&&f[k]*2000>=cnt)
            ans[cnt++]=i;
        f[0]=0;
    }
    while(q--)
    {
    
    
        int p;cin>>p;
        cout<<ans[p]<<endl;
    }
    return 0;
}

}

Guess you like

Origin blog.csdn.net/Joker_He/article/details/110500968