原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870

原题:

Rating

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 415 Special Judge

Problem Description
   A little girl loves programming competition very much. Recently, she has found a new kind of programming competition named "TopTopTopCoder". Every user who has registered in "TopTopTopCoder" system will have a rating, and the initial value of rating equals to zero. After the user participates in the contest held by "TopTopTopCoder", her/his rating will be updated depending on her/his rank. Supposing that her/his current rating is X, if her/his rank is between on 1-200 after contest, her/his rating will be min(X+50,1000). Her/His rating will be max(X-100,0) otherwise. To reach 1000 points as soon as possible, this little girl registered two accounts. She uses the account with less rating in each contest. The possibility of her rank between on 1 - 200 is P for every contest. Can you tell her how many contests she needs to participate in to make one of her account ratings reach 1000 points?
 
Input
   There are several test cases. Each test case is a single line containing a float number P (0.3 <= P <= 1.0). The meaning of P is described above.
 
Output
   You should output a float number for each test case, indicating the expected count of contest she needs to participate in. This problem is special judged. The relative error less than 1e-5 will be accepted.
 
Sample Input
1.000000 0.814700
 
Sample Output
39.000000 82.181160
 
Author
FZU
 
Source
2014 Multi-University Training Contest 1
 
Recommend
We have carefully selected several similar problems for you:  4882 4881 4880 4879 4878 

题意大概是这样:09开了两个号从零单排,势要上2000分。每个号都是0分开始,赢一场加50分,输一场扣100分,不会跌破0分。09每次都用分低的号来打,给出09打一场的胜率P,求有号达到2000分所要打的场数的期望值。

题解:

就是高斯消元求期望!(其实可以DP,就是先把公式变形一下,弄成可以DP的形式,然后只用写20行……尿了,下面是说高斯消元的,懂了的话就可以自己去DP了……

首先看一下期望怎么求,先把一个号的状态分成21个点,代表0分、50分、100分、……2000分,以后就以1代替50,从零单排上2000分变为从零单排上20分。两个号的话,用(x,y)来表示,为减少状态,设x<=y,这样就去掉了很多个点,最后只剩下两百多个点了。两百多个点与各个状态的对应,这个可以用map、pair来实现。

然后把每个点的输和赢都当一条边,这样能画出一个超碉的有向图。观察图,可以发现每个点都有两个出边(因为都有输和赢嘛,除了最后一个点,因为09刷到2000分就不打了)。设E(P)为P点到终点的步数的期望,E(终点)=0。

有:E(P)=p*E(Q)+q*E(R)+1,Q为P赢了到达的点,R为P输了到达的点,R可以等于P。

对每个P列这个式子,这样就可以列一个21元一次方程组,然后用高斯消元求解方程组,E(0,0)就为所求的期望。

我的高斯消元是从http://blog.csdn.net/duanxian0621/article/details/7408887 弄来的,把整数改成小数,整了挺久才弄好。

代码:

  1 /* 用于求整数解得方程组. */
  2
  3 #include <iostream>
  4 #include<cstdio>
  5 #include <cstring>
  6 #include <cmath>
  7
  8 #include<map>
  9
 10 #define mp make_pair
 11 using namespace std;
 12
 13 const int maxn = 333;
 14
 15 int equ, var; // 有equ个方程,var个变元。增广阵行数为equ, 分别为0到equ - 1,列数为var + 1,分别为0到var.
 16 double a[maxn][maxn];
 17 double x[maxn]; // 解集.
 18 bool free_x[maxn]; // 判断是否是不确定的变元.
 19 int free_num;
 20
 21 map<pair<int,int>,int> S;
 22 int lit[maxn];
 23 int big[maxn];
 24
 25 void Debug(void)
 26 {
 27     int i, j;
 28     for (i = 0; i < equ; i++)
 29     {
 30         for (j = 0; j < var + 1; j++)
 31         {
 32             printf("%6.2lf",a[i][j]);
 33         }
 34         cout << endl;
 35     }
 36     cout << endl;
 37 }
 38
 39 //inline int gcd(int a, int b)
 40 //{
 41 //    int t;
 42 //    while (b != 0)
 43 //    {
 44 //        t = b;
 45 //        b = a % b;
 46 //        a = t;
 47 //    }
 48 //    return a;
 49 //}
 50 //
 51 //inline int lcm(int a, int b)
 52 //{
 53 //    return a * b / gcd(a, b);
 54 //}
 55
 56 // 高斯消元法解方程组(Gauss-Jordan elimination).(-2表示有浮点数解,但无整数解,-1表示无解,0表示唯一解,大于0表示无穷解,并返回自由变元的个数)
 57 int Gauss(void)
 58 {
 59     int i, j, k;
 60     int max_r; // 当前这列绝对值最大的行.
 61     int col; // 当前处理的列.
 62     double ta, tb;
 63     int LCM;
 64     double teS;
 65     int free_x_num;
 66     int free_index;
 67     // 转换为阶梯阵.
 68     col = 0; // 当前处理的列.
 69     for (k = 0; k < equ && col < var; k++, col++)
 70     {
 71         // 枚举当前处理的行.
 72         // 找到该col列元素绝对值最大的那行与第k行交换.(为了在除法时减小误差)
 73         max_r = k;
 74         for (i = k + 1; i < equ; i++)
 75         {
 76             if (fabs(a[i][col]) > fabs(a[max_r][col])) max_r = i;
 77         }
 78         if (max_r != k)
 79         {
 80             // 与第k行交换.
 81             for (j = k; j < var + 1; j++) swap(a[k][j], a[max_r][j]);
 82         }
 83         if (a[k][col] == 0)
 84         {
 85             // 说明该col列第k行以下全是0了,则处理当前行的下一列.
 86             k--;
 87             continue;
 88         }
 89         for (i = k + 1; i < equ; i++)
 90         {
 91             // 枚举要删去的行.
 92             if (a[i][col] != 0)
 93             {
 94 //                LCM = lcm(fabs(a[i][col]), fabs(a[k][col]));
 95 //                ta = LCM / fabs(a[i][col]), tb = LCM / fabs(a[k][col]);
 96                 ta=1.0;
 97                 tb=fabs(a[i][col])/fabs(a[k][col]);
 98                 if (a[i][col] * a[k][col] < 0) tb = -tb; // 异号的情况是两个数相加.
 99                 for (j = col; j < var + 1; j++)
100                 {
101                     a[i][j] = a[i][j] * ta - a[k][j] * tb;
102                 }
103             }
104         }
105     }
106     //Debug();
107     // 1. 无解的情况: 化简的增广阵中存在(0, 0, ..., a)这样的行(a != 0).
108     for (i = k; i < equ; i++)
109     {
110         // 对于无穷解来说,如果要判断哪些是自由变元,那么初等行变换中的交换就会影响,则要记录交换.
111         if (a[i][col] != 0) return -1;
112     }
113     // 2. 无穷解的情况: 在var * (var + 1)的增广阵中出现(0, 0, ..., 0)这样的行,即说明没有形成严格的上三角阵.
114     // 且出现的行数即为自由变元的个数.
115     if (k < var)
116     {
117         // 首先,自由变元有var - k个,即不确定的变元至少有var - k个.
118         for (i = k - 1; i >= 0; i--)
119         {
120             // 第i行一定不会是(0, 0, ..., 0)的情况,因为这样的行是在第k行到第equ行.
121             // 同样,第i行一定不会是(0, 0, ..., a), a != 0的情况,这样的无解的.
122             free_x_num = 0; // 用于判断该行中的不确定的变元的个数,如果超过1个,则无法求解,它们仍然为不确定的变元.
123             for (j = 0; j < var; j++)
124             {
125                 if (a[i][j] != 0 && free_x[j]) free_x_num++, free_index = j;
126             }
127             if (free_x_num > 1) continue; // 无法求解出确定的变元.
128             // 说明就只有一个不确定的变元free_index,那么可以求解出该变元,且该变元是确定的.
129             teS = a[i][var];
130             for (j = 0; j < var; j++)
131             {
132                 if (a[i][j] != 0 && j != free_index) teS -= a[i][j] * x[j];
133             }
134             x[free_index] = teS / a[i][free_index]; // 求出该变元.
135             free_x[free_index] = 0; // 该变元是确定的.
136         }
137         return var - k; // 自由变元有var - k个.
138     }
139     // 3. 唯一解的情况: 在var * (var + 1)的增广阵中形成严格的上三角阵.
140     // 计算出Xn-1, Xn-2 ... X0.
141     for (i = var - 1; i >= 0; i--)
142     {
143         teS = a[i][var];
144         for (j = i + 1; j < var; j++)
145         {
146             if (a[i][j] != 0) teS -= a[i][j] * x[j];
147         }
148         //if (teS % a[i][i] != 0) return -2; // 说明有浮点数解,但无整数解.
149         x[i] = teS / a[i][i];
150     }
151     return 0;
152 }
153
154 int main(void)
155 {
156     int i, j,k;
157     int lvln=21;//21
158     int fin;
159     double P,Q;
160     k=0;
161     for(i=0; i<lvln-1; i++)
162         for(j=0; j<=i; j++)
163         {
164             lit[k]=j;
165             big[k]=i;
166             S[mp(j,i)]=k;
167             k++;
168         }
169     lit[k]=lvln-2;
170     big[k]=lvln-1;
171     S[mp(lit[k],big[k])]=k;
172     k++;
173     equ=k;
174     var=k;
175     while (scanf("%lf", &P) != EOF)
176     {
177         Q=1.0-P;
178         memset(a, 0, sizeof(a));
179         memset(x, 0, sizeof(x));
180         memset(free_x, 1, sizeof(free_x)); // 一开始全是不确定的变元.
181 //        for (i = 0; i < equ; i++)
182 //            for (j = 0; j < var + 1; j++)
183 //                scanf("%d", &a[i][j]);
184         a[k-1][k-1]=1;
185         a[k-1][var]=0;
186         for(i=0; i<k-1; i++)
187         {
188             //cout<<i<<'.'<<lit[i]<<','<<big[i]<<endl;
189             if(lit[i]!=big[i]) a[i][S[mp(lit[i]+1,big[i])]]+=P;
190             else a[i][S[mp(big[i],lit[i]+1)]]+=P;
191             a[i][S[mp(max(lit[i]-2,0),big[i])]]+=Q;
192             //cout<<max(lit[i]-2,0)<<','<<big[i]<<','<<S[mp(max(lit[i]-2,0),big[i])]<<endl;
193             a[i][var]-=1.0;
194             a[i][i]-=1.0;
195         }
196         //Debug();
197         free_num = Gauss();
198         //Debug();
199 //        if (free_num == -1) printf("无解!\n");
200 //        else if (free_num == -2) printf("有浮点数解,无整数解!\n");
201 //        else if (free_num > 0)
202 //        {
203 //            printf("无穷多解! 自由变元个数为%d\n", free_num);
204 //            for (i = 0; i < var; i++)
205 //            {
206 //                if (free_x[i]) printf("x%d 是不确定的\n", i + 1);
207 //                else printf("x%d: %d\n", i + 1, x[i]);
208 //            }
209 //        }
210 //        else
211 //        {
212 //            for (i = 0; i < var; i++)
213 //            {
214 //                printf("x%d %d,%d: %lf\n", i + 1,lit[i],big[i], x[i]);
215 //            }
216 //        }
217 //        printf("\n");
218         printf("%.6lf\n",x[0]);
219     }
220     return 0;
221 }

View Code

转载于:https://www.cnblogs.com/yuiffy/p/3871544.html

HDU4870_Rating_双号从零单排_高斯消元求期望相关推荐

  1. 【bzoj2460】[BeiJing2011]元素 贪心+高斯消元求线性基

    题目描述 相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力取决于使用的矿石. 一般地,矿石越多则法力越强,但物极必反 ...

  2. c++用类实现高斯消元法求解线性方程组的解_高斯消元

    高斯消元 众所周知,高斯消元是线性代数中重要的一课.通过矩阵来解线性方程组.高斯消元最大的用途就是用来解多元一次方程组. 前置技能 1.线性方程组 线性方程组是各个方程关于未知量均为一次的方程组(例如 ...

  3. 矩阵与高斯消元【矩阵乘法,高斯消元求线性方程组,求行列式】 全网最详,附例题与姊妹篇 一万三千字详解

    (详解)矩阵快速幂详解与常见转移矩阵的构造_秦小咩的博客-CSDN博客_矩阵快速幂转移矩阵 目录 矩阵乘法 矩阵快速幂 伪代码模板 例题一 例题2 例题三 例题四 高斯消元 整形高斯消元 浮点型高斯消 ...

  4. 【BZOJ2115】[Wc2011] Xor 高斯消元求线性基+DFS

    [BZOJ2115][Wc2011] Xor Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ...

  5. 洛谷 - P4783 【模板】矩阵求逆(高斯消元求逆矩阵)

    题目链接:点击查看 题目大意:给出一个 n * n 的矩阵,求出其逆矩阵,mod 为 1e9 + 7,若不存在输出 No Solution 题目分析:囤个模板,原理就是,初始时在原矩阵右侧设置一个单位 ...

  6. P6030-[SDOI2012]走迷宫【高斯消元,tarjan,期望dp】

    正题 题面链接:https://www.luogu.com.cn/problem/P6030 题目大意 nnn个点的一张有向图,求起点到终点的期望步数.保证每个强连通分量大小不超过100100100. ...

  7. BZOJ:4820: [Sdoi2017]硬币游戏BZOJ:1444: [Jsoi2009]有趣的游戏(高斯消元求概率)

    1444: [Jsoi2009]有趣的游戏 4820: [Sdoi2017]硬币游戏 这两道题都是关于不断随机生成字符后求出现给定字符串的概率的问题. 第一题数据范围较小,将串建成AC自动机以后,以A ...

  8. 2020 icpc济南 A - Matrix Equation (高斯消元求自由元个数)

    链接: A - Matrix Equation 题意: 给一个 A 矩阵 一个 B 矩阵(矩阵元素为 0 或 1),求有多少个 C 矩阵 满足 A X C = B . C (叉乘 和 点乘). 思路: ...

  9. 中石油训练赛 - Switches(高斯消元求逆矩阵+逆矩阵求线性方程组)

    题目大意:给出一个 n * n 的布尔矩阵表示开关与灯的关系,现在每个灯来说,是否存在一种开关的集合,使得恰好使得只有当前灯是打开状态,其余灯都是熄灭状态,分别输出方案 题目分析:将开关视为变元,将灯 ...

最新文章

  1. 「Linux」作怪的网络
  2. dedecms的特性-----不完整
  3. 远程登录linux进程的状态_Linux实操篇 - 远程登录到Linux系统
  4. [转载 整理]C语言链表实例
  5. 每日一博 - 常见的Spring事务失效事务不回滚案例集锦
  6. 数据蒋堂 | 怎样看待存储过程的移植困难
  7. [待解决]自定义头像时使用vue-cropper进行图片裁剪,得到的是base64格式的图片,如何对接file类型的api接口
  8. java用户名检查数据库_登入界面账号密码是访问数据库,但登入问题时if判断时就是执行不了...
  9. web前端开发初学者十问集锦(3)
  10. mysql索引数据结构图解_干货:mysql索引的数据结构
  11. linux内核配置成qspi挂载,【分享】在Linux/U-Boot里为QSPI Flash使用UBIFS
  12. CMM3学习笔记二—工程类PA之需求管理(REQM)
  13. arcpy批量重命名
  14. Linux中压缩文件后生成,在 Linux系统中,压缩文件后生成后缀为.gz文件的命令是 gzip 。...
  15. 曼昆微观经济学--十大原理
  16. 推荐一款待办事项和日程管理的微信小程序——腾讯待办
  17. BCD码和ASCII码的相互转换
  18. 不想重置路由器,如何由已连接设备快速获取wifi密码?
  19. html 设置横向打印,电脑打印怎么横向打印出来_打印机设置横向打印的图文教程...
  20. Marlin:Preprocessing zkSNARKs with Universal and Updatable SRS学习笔记

热门文章

  1. 用Python自动刷新抢12306火车票(附源码)
  2. 是个有趣的实验(10 interesting experiments)
  3. 【芝麻背调百科】HR们小心,一张离职证明,有可能让企业损失惨重!
  4. 测试用例设计_如何提高测试覆盖率
  5. 高效使用latex编辑数学公式
  6. MySQL limite用法
  7. 阿朱,是时候拥抱 Linux 了
  8. final, finally, finalize有什么区别?
  9. php验证码zhuc_微信小程序实例:实现随机验证码(附代码)
  10. 2021国家开放大学网络工程与组网技术形考测试(全)