Codeforces 768D Jon and Orbs

2 篇文章 0 订阅
2 篇文章 0 订阅

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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值