HDU 4672 Dice YY报告

题意:给定一个m面的色子。投色子,然后问你期望值为多少次时  后n次都相同或后n次都不相同

解题思路:完全YY的,0的话就是关于m的等比数列和,如果是1的话,就是一个类似于秦九韶算法的分数和;;;比赛后八分钟A了。。可惜。

官方:

设dp[i]表示当前在 已经投掷出 i个 不相同/相同 这个状态时期望还需要投掷多少次,然后dp[i] 有如下等式:

相同:

    //dp[0] = 1 + dp[1]

    //dp[1] = 1 + ((m-1)dp[1] + dp[2]) / m

    //dp[i] = 1 + ((m-1)dp[1] + dp[i+1]) / m

    //...

    //dp[n] = 0;

不相同:

    //dp[0] = 1 + dp[1]

    //dp[1] = 1 + (dp[1] + (m-1) dp[2]) / m

    //dp[2] = 1 + (dp[1] + dp[2] + (m-2) dp[3]) / m

    //dp[i] = 1 + (dp[1] + dp[2] + ... dp[i] + (m-i)dp[i+1]) / m

    //...

    //dp[n] = 0;

。。于是可以高斯消元。。对于第一问。。我们发现就是相当于 Typing Monkey 问题中字符串是 AAAA..AA 这一特殊情况。。解得递推式:

dp[n] = 0

dp[n-1] = dp[n] * m + 1

。。。

解开后等于等比数列求和。

(也可以直接得到这个公式。。。因为在当前状态只有 m/1 的概率可以进入下一状态,否则要重新来过。。而这一步会另总的步数 + 1。)

对于第二问。。

现在设s[i]=sigma{dp[i], 1..i},对s[i] 列方程
每个方程是关于三个相邻的s[i] 的,然后就可以线性时间解出来了。

也可以设 d[i] = dp[i] - dp[i+1].

可以得到 d[i] =  m * d[i-1]  / (m-i)

然后就是解一元一次方程...

解题代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 
 5 long long Pow(int b ,int n)
 6 {
 7   long long ans = 1 ;
 8 
 9   for(int i = 1;i <= n; i ++)
10     ans *= b;
11   return ans;
12 }
13 long long  do1(int b,int n )
14 {
15    if(b == 1)
16       return 1;
17    return (1-Pow(b,n))/(1-b);
18 }
19 double do2(int n,int k ,int i )
20 {
21     if(i == k )
22         return (n*1.0/i);
23    return n*1.0/i*(1 + do2(n,k,i-1));
24 }
25 int main()
26 {
27   int t;
28   while(scanf("%d",&t) != EOF)
29   {
30     while(t--)
31     {
32       int a, b , c ;
33       scanf("%d %d %d",&a,&b,&c);
34       if(a == 0 )
35       {
36         printf("%lld.000000000
",do1(b,c));
37       }
38       else
39       {
40         printf("%.9f
",do2(b,b-c+1,b));
41       }
42     }
43   }
44   return 0 ;
45 }
View Code
没有梦想,何谈远方
原文地址:https://www.cnblogs.com/zyue/p/3241724.html