HDU-1493 QQpet exploratory park(概率dp)

HDU-1493 QQpet exploratory park
Time Limit: 1000 ms / Memory Limit: 32768 kb
Description
Today, more and more people begin to raise a QQpet. You can get a lot of pleasure from it, although it does not have a real life and it calls for huge patience to take care of it. There is a place called QQpet exploratory park in the world. Every week, you can get a chance to have a joy there for free. The whole park contains 61 grids in a line, numbered from 0 to 60. Ten of them are important grids which will touch off ( 引发 ) an incident when the pet stands on. They are 5, 12, 22, 29, 33, 38, 42, 46, 50 and 55. Your pet is standing on the gird of number 0 in the beginning. You can toss the die ( 掷骰子 ) 10 times. Each time, the pet goes ahead n steps which n is the number from the die ( n ∈{ 1, 2, …, 6 } ). If your RP is great enough( calls RPG for short ), you will get many surprises in the important grids, such as some yuanbao( the money in QQpet world ), an improvement of your pet’s ability, and the most attractive gift-package. Now, your task is to calculate the probability(概率) of touching each important grid.

Input
The first line of the input contains an integer t– determining the number of datasets. Then t lines follows. Each line contains 6 numbers pi, i ∈{ 1, 2, …, 6 }, indicating the probability of getting 1 to 6 after you toss the die every time . p1+ p2+ … + p6 = 1.

Output
For each test case, output the probability of touching each important grid. accurate up to 1 decimal places. There is a blank line between test cases. See the Sample Output to get the exactly output format.

Sample Input
2
0.000 1.000 0.000 0.000 0.000 0.000
0.500 0.000 0.000 0.000 0.000 0.500
Sample Output
5: 0.0%
12: 100.0%
22: 0.0%
29: 0.0%
33: 0.0%
38: 0.0%
42: 0.0%
46: 0.0%
50: 0.0%
55: 0.0%

5: 3.1%
12: 30.5%
22: 27.3%
29: 24.6%
33: 21.9%
38: 10.9%
42: 0.8%
46: 0.0%
50: 4.4%
55: 1.0%
Source
“2006校园文化活动月”之“校庆杯”大学生程序设计竞赛暨杭州电子科技大学第四届大学生程序设计竞赛

要明白DP中状态的含义,理解DP中的状态变得非常重要,这道概率DP,
用两维,第一维表示所有站点,第二维表示掷筛子10次,这样就能表示所有的状态,而且符合计算过程了。
dp[i][j]:第j次掷筛子刚好走到第i个站点的概率,dp[i][j]+=dp[i-k][j-1]*p[k] 1<=k<=6
设计的动态规划方程要能表示所有状态

#include<bits/stdc++.h>
using namespace std;
double dp[65][12];
double ans[15];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
       for(int i = 1;i <= 6;++i)
       {
           scanf("%lf",&ans[i]);
//           cout << ans[i] << endl;
       }
       memset(dp,0,sizeof(dp));
       for(int i = 1;i <= 6;++i)
            dp[i][1] = ans[i];
       for(int i = 2;i <= 10;++i)
       {
           for(int j = 0;j <= 60;++j)
           {
               for(int k = 1;k <= 6;++k)
               {
                   if(j >= k)
                      dp[j][i] += dp[j - k][i - 1] * ans[k];
               }
           }
       }
//       for(int i = 0;i <= 60;++i)
//       {
//           for(int j = 1;j <= 10;++j)
//           {
//               printf("%f ",dp[i][j]);
//           }
//           printf("\n");
//       }
        double ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[5][i];
        printf("5: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[12][i];
        printf("12: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[22][i];
        printf("22: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[29][i];
        printf("29: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[33][i];
        printf("33: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[38][i];
        printf("38: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[42][i];
        printf("42: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[46][i];
        printf("46: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[50][i];
        printf("50: %.1lf%%\n",ans * 100);
        ans = 0;
        for(int i = 1;i <= 10;++i)
            ans += dp[55][i];
        printf("55: %.1lf%%\n",ans * 100);
        if(t)
            printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/80303105