codeforces 464D World of Darkraft - 2 (概率dp)

题意:

一个人去玩world Darkraft2这个游戏,他有k个装备栏,每个装备初始时的装备等级都是1,假设现在的某个装备栏的装备等级是j,每次打一个怪兽会随机获得某个装备栏中对应的装备(获得概率相同),并且会随机得到[1,j+1]之间等级的装备,当然这个人会选择最好的装备留下。换下来的装备就会卖掉,装备的价格等于等级数。问这个人获得的金币数的期望是多少?

题解:

见注释 dp[i][j]表示打了i个怪这个装备等级为j到把怪全部打完金币数的期望。


/**
根据数理统计对于一个样本的xi,如果xi相互独立那么:E[∑xi]=∑E[xi]=kE[x]=kE[xi];那么 E[xi]=1/k*E[∑xi];
PS: xi表示某个部位的装备,这些装备之间是独立的
E[i][j] = 1/k*{ ∑(E[i+1][j]+t)/(j+1) + (E[i+1][j+1]+j)/(j+1) } + (1-1/k)*E[i+1][j];
化简处理下
这题用O(n^2)算法明显超时,但是据大牛说对于大于600的j来说影响很小所以j只要转移到600
*/
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef long long ll;
const int oo=0x3f3f3f3f;
const ll OO=1LL<<61;
const ll MOD=10007;
const int maxn=100000+5;
double dp[2][600];

int main()
{
    int n,k;
    while(scanf("%d %d",&n,&k)!=EOF)
    {
        memset(dp,0,sizeof dp);
        for(int i=n-1;i>=0;i--)
        {
            for(int j=1;j<600;j++)
            {
                double t1=(1.0*j*dp[(i+1)%2][j]+dp[(i+1)%2][j+1]+1.0*j)/(j+1)+0.5*j;
                double t2=1.0*(k-1)*dp[(i+1)%2][j];
                dp[i%2][j]=(t1+t2)/k;
            }
        }
        printf("%.10lf\n",k*dp[0][1]);
    }
    return 0;
}
/***
*/




你可能感兴趣的:(codeforces 464D World of Darkraft - 2 (概率dp))