TC SRM656 Div2 500 RandomPancakeStack

Problem Statement

Charlie has N pancakes. He wants to serve some of them for breakfast. We will number the pancakes 0 through N-1. For each i, pancake i has width i+1 and deliciousnessd[i].

Charlie chooses the pancakes he is going to serve using the following randomized process: He starts by choosing the first pancake uniformly at random from all the pancakes he has. He places the chosen pancake onto a plate. This pancake now forms the bottom of a future stack of pancakes. Then, Charlie repeats the following procedure:

  1. If there are no more pancakes remaining, terminate.
  2. Choose a pancake uniformly at random from the pancakes that have not been chosen yet.
  3. If the width of this pancake is greater than the width of the pancake on top of the stack, terminate without taking it.
  4. Place the chosen pancake on top of the stack and go back to step 1.

You are given the int[] d with N elements. The total deliciousness of a serving of pancakes is the sum of the deliciousness of all pancakes used in the serving. Compute and return the expected value of the total deliciousness of the pancakes chosen by Charlie.

Definition

  • ClassRandomPancakeStackDiv2
  • MethodexpectedDeliciousness
  • Parametersvector<int>
  • Returnsdouble
  • Method signaturedouble expectedDeliciousness(vector<int> d)
(be sure your method is public)

Limits

  • Time limit (s)2.000
  • Memory limit (MB)256

Notes

  • Your return value must have an absolute or relative error smaller than or equal to 1e-6

Constraints

  • The number of elements in d will be between 1 and 10, inclusive.
  • Each element of d will be between 1 and 100, inclusive.

Test cases

    • d{ 1, 1, 1 }
    Returns 1.6666666666666667
    The following scenarios may occur:
    1. With probability 1/3, Charlie chooses pancake 0 first. In this case he won't be able to add any more pancakes and the total deliciousness of his serving of pancakes will be 1.
    2. With probability 1/3, Charlie chooses pancake 1 first. What happens in the second round? With probability 1/2 he will choose pancake 0 and with probability 1/2 it will be pancake 2. In the first case the total deliciousness of Charlie's pancakes will be 2, in the second case it will be 1.
    3. With probability 1/3, Charlie chooses pancake 2 first. If he chooses pancake 0 next, the total deliciousness of his pancakes will be 2. If he happens to choose pancake 1 next (followed by pancake 0 in the third round), the total deliciousness will be 3.
    Summing this up, we get the expected deliciousness to be 1/3 * (1) + 1/3 * (1/2 * 1 + 1/2 * 2) + 1/3 * (1/2 * 2 + 1/2 * 3) = 5/3 = 1.666...
    • d{ 10, 20 }
    Returns 20.0
    • d{ 3, 6, 10, 9, 2 }
    Returns 9.891666666666667
    • d{ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }
    Returns 10.999999724426809
    • d{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
    Returns 7.901100088183421
    • d{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
    Returns 1.7182818011463845

解析

概率DP。dp[i][j]表示选了i个饼,堆顶的饼的编号是j的概率。dp[i][j]*d[j]是走到这个状态对答案的贡献。dp[1][N]要特殊处理。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <typeinfo>
#include <fstream>

using namespace std;
double dp[15][15],d[15];

class RandomPancakeStackDiv2 {
    public:
    double expectedDeliciousness(vector<int> D) {
		memset(dp,0,sizeof(dp));
		int N=D.size();
		for(int i=0;i<N;i++) d[i+1]=D[i];
		
		dp[0][N]=1;dp[1][N]=1/(double)N;
		double ans=0;
		for(int i=1;i<=N;i++)
			for(int j=1;j+i-1<=N;j++)
			{
				for(int k=N;k>j;k--) dp[i][j]+=dp[i-1][k]/(N-i+1);
				ans+=dp[i][j]*d[j];
			}
		/*
		for(int i=1;i<N;i++)
			for(int j=1;j+i-1<=N;j++)
				ans+=dp[i][j]*((double)(N-j-i+1)/(double)(N-i));
		*/
        return ans;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值