URAL 1776 Anniversary Firework 概率dp+区间dp

A - Anniversary Firework

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status Practice URAL
1776

Appoint description: 
System Crawler  (2016-05-06)

Description

Denis has to prepare the Ural State University 90th anniversary firework. He bought n rockets and started to think of the way he should launch them. After a pair of sleepless nights he invented the following algorithm.

All n rockets are placed on the surface in a single line. The interval between two consecutive salvos is ten seconds. The leftmost and the rightmost rocket are launched in the first salvo. After i salvos are
fired, all non-empty segments between two neighboring launched rockets are considered. One rocket is chosen randomly and uniformly at each of these segments. All chosen rockets are launched in the (i + 1)-st salvo. Algorithm runs until all rockets
are launched.

Calculate the average duration in seconds of such a firework.

Input

The only input line contains an integer n (3 ≤ n ≤ 400) , which is the number of rockets bought by Denis.

Output

Output the expected duration of the firework in seconds, with absolute or relative error not exceeding 10 ?6.

Sample Input

input output
5
26.66666666666

Notes

First, the rockets with numbers 1 and 5 are launched. 10 seconds later the rocket 3 is launched with probability 1/3; in that case, 10 more seconds later the rockets 2 and 4 are launched, and the firework is over after 20 seconds. In case the rocket 2 or
rocket 4 is launched in the second salvo (this happens with probability 2/3), the firework is over after 30 seconds.

题目的意思给你n个火箭排成一排

一开始点燃第一个和最后一个火箭

然后每次只能在点燃过的火箭中的火箭

每两次点燃火箭的间隔时间为10s求

点燃n个火箭等待时间的期望

设dp【i,j】表示i个火箭等待了j次

那么求花费j次的概率为 dp[【i,j】=dp【i,j-1】

然后就枚举长度和次数

ACcode:

#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 404
using namespace std;
double dp[maxn][maxn];
int main(){
    int n;
    while(~scanf("%d",&n)){
        n-=2;
        for(int i=0;i<=n;++i)for(int j=i;j<=n;++j)dp[i][j]=1.0;
        for(int i=1;i<=n;i++){
            double e=1.0/i;
            for(int j=2;j<i; j++){
                dp[i][j]=dp[i][j-1];
                for(int k=1;k<=i;k++){
                    int l=k-1,r=i-k;
                    double p1=dp[l][j-1],p2=dp[r][j-1],p3=dp[l][j-2],p4=dp[r][j-2];
                    dp[i][j]+=e*(p1*p2-p3*p4);
                }
            }
        }
        double ans = 0;
        for(int i = 1; i <= n; i++){
            ans += (dp[n][i]-dp[n][i-1])*i*10;
        }
        printf("%.11lf\n",ans);
    }
    return 0;
}
时间: 2024-10-19 08:52:33

URAL 1776 Anniversary Firework 概率dp+区间dp的相关文章

POJ #3267 The Cow Lexicon 型如&quot; E[j] = opt{D+w(i,j)} &quot;的简单DP 区间DP

Description 问题的描述以及输入输出的样例可以看这里:链接 思路 虽然 DISCUSS 中总有人说水题,但是我觉得这道题的质量可以 (或许我比较弱ORZ ,在做过的 DP 题里算 medium 难度. 题目的意思是给你一个主串和一堆子串,需要你将子串和主串完全匹配上,在匹配过程中可以删除主串中匹配不上的字符,最后统计出被删除的最少字符数目. 比如主串是 carmsr ,子串有 car .mr 两种.可以只用 car 去匹配,那么匹配不上的字符有 m.s.r 三个,所以需要删除三个字符:

Treats for the Cows POJ - 3186 dp 区间dp

//dp[i][j]表示第i次从左边取,第j次从右边取的价值,所以我们可以得到状态方程 //dp[i][j]=max(dp[i-1][j]+(i+j)*a[i],dp[i][j-1]+(i+j)*a[n-j+1]) (i > 0 && j > 0 ) //dp[i][0]=dp[i-1][0]+i*a[i],dp[0][i] dp[0][i-1]+i*a[n-i+1]; #include<cstdio> #include<cmath> #include&

UVA 10529 - Dumb Bones(概率+区间dp)

UVA 10529 - Dumb Bones 题目链接 题意:你试图把一些多米诺骨牌排成直线,然后推倒它们.但是如果你在放骨牌的时候不小心把刚放的骨牌碰倒了,它就会把相临的一串骨牌全都碰倒,而你的工作也被部分的破坏了. 比如你已经把骨牌摆成了DD__DxDDD_D的形状,而想要在x这个位置再放一块骨牌.它可能会把左边的一块骨牌或右边的三块骨牌碰倒,而你将不得不重新摆放这些骨牌. 这种失误是无法避免的,但是你可以应用一种特殊的放骨牌方法来使骨牌更多的向一个方向倒下. 给出你要摆放的骨牌数目,以及放

POJ 1141 Brackets Sequence (区间DP)

Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a regular sequence, then (S) and [S] are both regular sequences. 3. If A and B are regular sequences, then AB is a regular

CSUOJ-1980 不堪重负的数(区间dp)

1980: 不堪重负的树 Submit Page   Summary   Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 57     Solved: 20 Description 小X非常喜欢树,然后他生成了一个大森林给自己玩.玩着玩着,小X陷入了沉思. 一棵树由N个节点组成,编号为i的节点有一个价值Wi. 假设从树根出发前往第i个节点(可能是树根自己),一共需要经过Di个节点(包括起点和终点),那么这个节点对这棵树产生的负担

【日常学习】【区间DP】codevs1048 石子归并题解

题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述 Input Description 第一行一个整数n(n<=100) 第二行n个整数w1,w2...wn  (wi <= 100) 输出描述 Output Description 一个整数表示最小合并代价 样例输入 Sample Input 4 4 1 1 4 样

树形DP URAL 1039 Anniversary Party

题目传送门 1 /* 2 题意:上司在,员工不在,反之不一定.每一个人有一个权值,问权值和最大多少. 3 树形DP:把上司和员工的关系看成根节点和子节点的关系,两者有状态转移方程: 4 dp[rt][0] += max (dp[son][1], dp[son][0]); //上司不去 5 dp[rt][1] += dp[son][0]; //上司去,员工都不去 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <

uva 10529 - Dumb Bones(概率+区间dp)

题目连接:uva 10529 - Dumb Bones 题目大意:给定n,表示要放n个骨牌,每次放下骨牌,有可能向左倒的概率为pl,向右倒的概率为pr,如果倒下,会将那一侧的骨牌全部推倒,可以选择位置先后放骨牌,问说一种放骨牌次数最少的期望是多少. 解题思路:dp[i]表示放i个骨牌需要的步数期望,维护一个最优放的位置,dp[i] = min\{ (从i-1到i的步数)} + (0到i-1的步数)} (从i-1到i的步数):dp[i?j?1]?pl+dp[j]?pr+11?pl?pr (0到i-

hdu 4412 Sky Soldiers(区间DP)

Sky Soldiers Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 559    Accepted Submission(s): 181 Problem Description An airplane carried k soldiers with parachute is plan to let these soldiers j