HDU3994(Folyd + 期望概率)

Mission Impossible

Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 227    Accepted Submission(s): 106
Special Judge

Problem Description

I.M.F.(Impossible
Missions Force) is a top secret spy organization in U.S. Ethan Hunt
have serviced in this organization for many years. Now, he is retired
and serves as a spy in a big company. Although he is very excellent, he
would make mistakes. For example, last time he invaded another company
to find some programming code. When he risked his life to steal the last
few pages of the code, he found that all of the letters on them are
only “}”. His boss is very angry. So, Ethan must finish this new mission
and he needs your help.

In
this new mission, Ethan successfully gets a big file in a computer and
decided to send this file from this computer to his boss’s computer
though the internet. We can assume the file is made of C small parts and
Ethan could only send one part each unit time.

The network
consists of n (n <= 200) computers, Ethan sits next to computer 1,
his boss sits next to computer 2. There exists a probability p[i][j]
between computer i and computer j, which means the probability of
successfully transferring each part from i to j is p[i][j]. However, all
of these links in the network are unidirectional (i.e. p[i][j] may be
different from p[j][i]). We defined the e[i][j] as the expected time to
send each part from i to j. For example, if p[i][j] = 10%, e[i][j] = 10
units.

You
may find that the probability would be very tiny and the expected time
could be very large since the route may be extremely long. Fortunately,
Ethan knows that he has m teammates sit next to several computers. He
can choose these computers as storage to shorten the transferring time.
(i.e. each of the n computers could be used as node
in any route, but only these m computers could be used as storages. Each
attempt to send a small part, successful or unsuccessful, takes
exactly one unite time, regardless of the number of links on the route.) So, he can do this mission as follows:

    • Choose a computer which includes the file (i.e. C parts of information) as computer u.
    • Choose
      another computer his boss or some teammate sits next to as computer v,
      and then takes time to transfer the file from u to v. If any part fails
      to be transferred, it will be resent immediately.
    • When the file is sent to his boss’s computer, the mission is finished.

To
satisfy his boss, Ethan must choose a route to make the total expected
time from computer 1(the computer near him) to computer 2(the computer
near his boss) minimum. You need to tell Ethan the minimum total
expected time.

It is an impossible mission aha? Why not have a try. It’s easier than expected.

Input

The first line contains an integer T, which means there are T test cases. Each test case is preceded by a blink line.

In
each test case, you know n (2 <= n <= 200), which means the
number of computers. Then an n*n matrix p(n) is following. p[i][j] means
the probability of successfully transferring each part from i to j. You
may assume that 0 <= p[i][j] <= 100.

Next line contains m
(m <= n) means there are m computer that could serve as storage (i.e.
the number of computers near Ethan, his teammates or his boss). Then a
line contains m integer shows these computers. You may assume that it
must contains computer 1 and computer 2.

The last line tells you there C parts in the big file. C is an integer which insure the answer is less than 1 000 000 000.

Output

For
each test case, you need to output a single line which contains the
minimum expected time of the transfer when Ethan chooses the best way to
finish his mission.

You’d better (not must) make the answer
rounded to 7 decimal places. Your answer would be considered correct if
each number has an absolute or relative error less than 10^-6.

Sample Input

2

5
0 1 20 0 0
0 0 0 0 0
0 0 0 50 90
0 20 0 0 0
0 0 0 90 0
3
1 2 5
10

4
0 100 0 0
100 0 100 0
0 100 0 100
0 0 100 0
0
1

Sample Output

111.111111
1.000000

感概:这题意我真是看了3遍啊!说明我这英语真是差啊,还不知道明天四级过的了不?

题意:求将文件从起点到终点通过中转站所学需要的最小的 期望时间。先求一个文件所需要的时间。题目给出了任意两点的成功率p。我们可以通过负二项分布成功一次的期望公式1/p,求出中转站任意两点的期望(PS:这里的期望是相加的,因为从i到j的这件情况与j到k的这种情况是无关的所以可以相加)。之后求出起点到终点最小期望再乘以文件数量即得所求。

收获:1.int型 * 1.0 可以转换为 double;

   2.folyd 既可以求出两点的最短路还可以求出最长路;

   3.负二项分布情况出现一次的期望公式 若这个情况发生的概率为p,那么这种情况出现一次的期望为1/p。

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
using namespace std;

const int INF=0x3f3f3f3f;
const double eps=1e-8;
const double PI=acos(-1.0);
#define maxn 500
double p[maxn][maxn];
double temp[maxn][maxn];
int sto[maxn];
int n, m;
void folyd_probability()
{
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
            {
                if ((i==j) || (j==k) || (i==k)) continue;
                p[i][j] = max(p[i][j], p[i][k]*p[k][j]);
            }
}
void folyd_expect()
{
    for(int k = 0; k < m; k++)
        for(int i = 0; i < m; i++)
            for(int j = 0; j < m; j++)
            {
                if ((sto[i]==sto[j]) || (sto[j]==sto[k]) || (sto[i]==sto[k])) continue;
                if (p[sto[i]][sto[k]]>=0 && p[sto[k]][sto[j]]>=0 && (p[sto[i]][sto[j]]<0 || p[sto[i]][sto[j]]>p[sto[i]][sto[k]]+p[sto[k]][sto[j]]))
                {
                    p[sto[i]][sto[j]] = p[sto[i]][sto[k]] + p[sto[k]][sto[j]];
                }
            }
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
            {
                scanf("%lf", &p[i][j]);
                p[i][j] = p[i][j]/100.0;
            }
        folyd_probability();

        scanf("%d", &m);
        for(int i = 0; i < m; i++)
            scanf("%d", &sto[i]);
        int i;
        for(i = 0; i < m; i++)
            if(sto[i] == 1)
            break;
        if(i == m)
            sto[m++] = 1;
        for(i = 0; i < m; i++)
            if(sto[i] == 2)
            break;
        if(i == m)
            sto[m++] = 2;

        for(i = 0; i < m; i++)
            for(int j = 0; j < m ;j++)
            {
                temp[sto[i]][sto[j]] = p[sto[i]][sto[j]];
                if(temp[sto[i]][sto[j]] < eps)
                    p[sto[i]][sto[j]] = -1;
                else
                    p[sto[i]][sto[j]] = 1.0/temp[sto[i]][sto[j]];
            }

        folyd_expect();
        int c;
        scanf("%d", &c);
        printf("%.6lf\n", p[1][2] * c);
    }
    return 0;
}
时间: 2024-11-06 16:34:59

HDU3994(Folyd + 期望概率)的相关文章

【NOIP模拟赛】黑红树 期望概率dp

这是一道比较水的期望概率dp但是考场想歪了.......我们可以发现奇数一定是不能掉下来的,因为若奇数掉下来那么上一次偶数一定不会好好待着,那么我们考虑,一个点掉下来一定是有h/2-1个红(黑),h/2+1个黑(红),而且一定是差不多相间的(我就是因为没有看出来这里才会去想组合数,然后......),那么我们发现只要一奇一偶,就可以组成一对,因为偶数一定是平的因此,我们发现在掉下来的那对之前都是红黑或黑红,但是到了这里就是红红或黑黑了,我们只要求出(异色的概率)^(h/2-1)*(同色的概率)就

HDU 3853 期望概率DP

期望概率DP简单题 从[1,1]点走到[r,c]点,每走一步的代价为2 给出每个点走相邻位置的概率,共3中方向,不动: [x,y]->[x][y]=p[x][y][0] ,  右移:[x][y]->[x][y+1]=p[x][y][1];  左移:[x][y]->[x+1][y]=p[x][y][2]; 问最后走到[r,c]的期望 dp[i][j]为从[i][j]点走到[r][c]的期望 有方程: dp[i][j]=    (dp[i][j]+2)*p[i][j][0]  +   (dp

POJ3682King Arthur&#39;s Birthday Celebration(数学期望||概率DP)

King Arthur is an narcissist who intends to spare no coins to celebrate his coming K-th birthday. The luxurious celebration will start on his birthday and King Arthur decides to let fate tell when to stop it. Every day he will toss a coin which has p

【BZOJ 3652】大新闻 数位dp+期望概率dp

并不难,只是和期望概率dp结合了一下.稍作推断就可以发现加密与不加密是两个互相独立的问题,这个时候我们分开算就好了.对于加密,我们按位统计和就好了;对于不加密,我们先假设所有数都找到了他能找到的最好的匹配(就是异或后为二进制最高位与n-1相等的最大数)并且算出其异或后的总和,然后我们按位贪心,带着所有的数(一开始我们假设所有的数是小于等于二进制最高位与n-1相等的最大数的所有数)从高位走向低位,每走一步,如果这一位是0,就会导致一半的数在这一位不能是1,减去这一半的数在这一位上的贡献,如果这一位

【复习】高斯消元解图上期望概率

复习了一下高斯消元解图上期望概率,笔记的话,就直接去看SengXian的blog吧.BZOJ 1444 - [Jsoi2009]有趣的游戏见https://blog.sengxian.com/solutions/bzoj-1444 #include <cstdio> #include <cstring> #include <algorithm> const int N=11; char s[N*2]; int n,m,l,cnt,trans[N*N][N],id[N*N

LightOJ 1030 Discovering Gold(期望 概率)

正推,到达i的概率为p[i],要注意除了1和n外,到达i的概率并不一定为1 概率表达式为p[i] += p[j] / min(n - j, 6) 从j带过来的期望为exp[i] += exp[j] / min(n - j, 6) 又到达i时有价值val[i],到达i的概率为p[i],故exp[i] += val[i] * p[i] #include<cstdio> #include<iostream> #include<cstdlib> #include<cstr

【BZOJ 2553】[BeiJing2011]禁忌 AC自动机+期望概率dp

我一开始想的是倒着来,发现太屎,后来想到了一种神奇的方法——我们带着一个既有期望又有概率的矩阵,偶数(2*id)代表期望,奇数(2*id+1)代表概率,初始答案矩阵一列,1的位置为1(起点为0),工具矩阵上如果是直接转移那么就是由i到j概率期望都乘上1/alphabet,特别的,对于一个包含禁忌串的节点直接由其父节点指向0,而且在计算期望是多加上他的概率,最后统计答案时把答案矩阵上所有的期望加和即可,这个方法很完美的被卡精了....... #include <cstdio> #include

Bzoj 3450: Tyvj1952 Easy 期望/概率,动态规划

3450: Tyvj1952 Easy Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 431  Solved: 325[Submit][Status][Discuss] Description 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(我们来简化一下这个游戏的规则有n次点击要做,成功了就是o,失败了就是x,分数是按comb计算的,连续a个comb就有a*a分,comb就是极大的连续o.比如ooxxxxooooxxx

【BZOJ 4832】 [Lydsy2017年4月月赛] 抵制克苏恩 期望概率dp

打记录的题打多了,忘了用开维记录信息了......我们用f[i][j][l][k]表示已经完成了i次攻击,随从3血剩j个,2血剩l个,1血剩k个,这样我们求出每个状态的概率,从而求出他们对答案的贡献并加和,一开始我用的期望忘了转移的时候不能用1而要用概率...... #include <cstdio> #include <cstring> #define r register using namespace std; typedef long double LD; inline i