Codeforces 768D Jon and Orbs

D. Jon and Orbs
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Jon Snow is on the lookout for some orbs required to defeat the white walkers. There are k different types of orbs and he needs at least one of each. One orb spawns daily at the base of a Weirwood tree north of the wall. The probability of this orb being of any kind is equal. As the north of wall is full of dangers, he wants to know the minimum number of days he should wait before sending a ranger to collect the orbs such that the probability of him getting at least one of each kind of orb is at least , where ε < 10 - 7.

To better prepare himself, he wants to know the answer for q different values of pi. Since he is busy designing the battle strategy with Sam, he asks you for your help.

Input
First line consists of two space separated integers k, q (1 ≤ k, q ≤ 1000) — number of different kinds of orbs and number of queries respectively.

Each of the next q lines contain a single integer pi (1 ≤ pi ≤ 1000) — i-th query.

Output
Output q lines. On i-th of them output single integer — answer for i-th query.

Examples
input
1 1
1
output
1
input
2 2
1
2
output
2
2

Problem Idea
解题思路:
【题意】
有k种魔法球,每天能取得一种,但不能选择是哪一种,每种的概率是相同的,求如果全部收集齐,其概率大于pi- ε/2000的概率

【类型】
动态规划,搜索。

【分析】
首先,这道题的解题思想是这样的——
i代表已经从n种中集齐i种,j表示第j天。
任何一天集齐i种的概率是前一天已经集齐i种今天收集i/n的概率。
加上前一天集齐i-1种的概率今天收集(n-i+1)的概率。
得到dp公式

d[i][j] = (d[i - 1][j] * j + d[i - 1][j - 1] * (n - j + 1)) / n;

然而对集齐n种的概率为也可以看作(d[i - 1][j] * j) / n + (d[i - 1][j - 1] * (n - j + 1)) / n;所以i的顺序对结果没有影响。

d[i][j] = (d[i - 1][j] * j + d[i - 1][j - 1] )( i * 1.0 ) / n;

【时间复杂度&&优化】
k最大为1000,天数可以看作约有10000天,最大是1e7。

题目链接→Codeforces 768D Jon and Orbs

AC代码

#include<algorithm>
#include <iostream>
#include  <ctype.h>
#include  <cstring>
#include  <fstream>
#include   <cstdio>
#include   <vector>
#include   <string>
#include    <cmath>
#include    <stack>
#include    <queue>
#include      <set>
#include      <map>
#define INF (1<<30)
#define PI acos(-1.0)
typedef long long ll;
using namespace std;
const int N = 5e5 + 5;
double d[10001][1001];
int main() {
    int i, j, n, m;
    scanf("%d%d", &n, &m);
    d[0][0] = 1;
    for (i = 1; i <= 10000; i++) 
        for (j = 1; j <= n; j++)
            d[i][j] = (d[i - 1][j] * j + d[i - 1][j - 1] * (n - j + 1)) / n;
    double a;
    while(m--) {
        scanf("%lf",&a);
        int l=0,r=10000;
        while(r!=l)
        {
            int mid=(l+r)>>1;
            if(d[mid][n]*2000>a){
                r=mid;
            }
            else
            {
                l=mid+1;
            }
        }
        printf("%d\n",r);

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lxworld123/article/details/56485748