2014多校第一场J题 || HDU 4870 Rating(DP || 高斯消元)
题意 :小女孩注册了两个比赛的帐号,初始分值都为0,每做一次比赛如果排名在前两百名,rating涨50,否则降100,告诉你她每次比赛在前两百名的概率p,如果她每次做题都用两个账号中分数低的那个去做,问她最终有一个账号达到1000分需要做的比赛的次数的期望值。
思路 :可以直接用公式推出来用DP做,也可以列出210个方程组用高斯消元去做。
(1)DP1:离散化。因为50,100,1000都是50的倍数,所以就看作1,2,20。这样做起来比较方便。
定义dp[i]为从 i 分数到达i+1分的期望,状态转移方程:
dp[i] = p+(1-p)*(1+dp[i-2]+dp[i-1]+dp[i]); 在前两百名里增加一分,当不在前两百名里的时候,扣两分,要回到 i+1 分就是1+dp[i-2]+dp[i-1]+dp[i].
mp[i][i]表示两个账号都从0分涨到 i 分的期望,所以mp[i+1][i] = mp[i][i]+dp[i], mp[i+1][i+1] = mp[i+1][i]+dp[i];
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h> using namespace std ; double dp[],mp[][] ; int main()
{
double p ;
while(scanf("%lf",&p) != EOF)
{
dp[] = / p ;
dp[] = / p / p ;
for(int i = ; i < ; i++)
dp[i] = + (-p)*(dp[i-]+dp[i-]+)/p ;
for(int i = ; i < ; i++)
{
mp[i+][i] = mp[i][i]+dp[i] ;
mp[i+][i+] = mp[i+][i] + dp[i] ;
}
printf("%.6lf\n",mp[][]) ;
}
return ;
}
(2)DP2:在网上看了一个线性的复杂度的,here,推公式很厉害。
先考虑一场比赛的情况,定义dp[k]为当前为k分,要达到20分时的期望回合数。
那么显然有 dp[0]=1+p*dp[1]+q*dp[0] 化简得 dp[0]=1/p+dp[1]
dp[1]=1+p*dp[2]+q*dp[0] 化简得 dp[0]=1/p+1/p^2+dp[2]
我们令 dp[0]=t[k]+dp[k] 那么t[k]就表示由0状态到达k状态所需的期望回合数。如果是要到达20分就是t[20]。
得到dp[k]=1+p*dp[k+1]+(1-p)*dp[k-2]
将dp[k]=dp[0]-t[k]和dp[k-2]=dp[0]-t[k-2]代入得 :
dp[0]=1/p+t[k]/p-(1-p)/p*t[k-2]+dp[k+1]
然后代入dp[k+1]=dp[0]-t[k+1]得:
t[k+1]=1/p+1/p*t[k]-(1-p)/p*t[k-2]
边界条件是 t[0]=0,t[1]=1/p,t[2]=1/p+1/p^2
知道这些就可以递推出所有需要的t[k]了。
因为是两个账号,所以变化一定是(0,0)——>(1,0)——>(1,1)——>……(19,18)——>(19,19)——>(20,19)
(0,0)->(0,1)需要的期望回合数是t[1]-t[0]. (0,1)->(1,1)需要的期望回合数是 t[1]-t[0]
(1,1)->(1,2)需要的期望回合数是t[2]-t[1]. (1,2)->(2,2)需要的期望回合数是 t[2]-t[1].
....
(18,18)->(18,19)需要的期望回合数是t[19]-t[18]. (18,19)->(19,19)需要的期望回合数是t[19]-t[18].
(19,19)->(19,20)需要的期望回合数是t[20]-t[19]。
全部加起来的结果就是t[19]*2+t[20]-t[19].
所以最后的复杂度可以是线性的,而且理论上对于k个账号也是适用的,这样就可以避开了高斯消元的做法了。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h> using namespace std ; double d[] ; int main()
{
double p ;
while(scanf("%lf",&p) != EOF)
{
d[] = ;
d[] = / p ;
d[] = / p + / (p * p) ;
for(int i = ; i <= ; i++)
d[i] = / p + d[i-] / p +(p - )*d[i-] / p ;
printf("%.6lf\n",d[] + d[]) ;
}
return ;
}
(3)高斯消元:
官方题解:
令(x, y)表示高分为x,低分为y的状态(x >= y),E(x, y)表示从(x, y)到达(1000, ?)的比赛场数期望。容易得到E(x, y) = P * E(x1, y1) + (1 - P) * E(x2, y2) + 1,其中,(x1, y1)表示rating上升后的状态,(x2, y2)表示rating下降后的状态。每50分一个状态,共有210个状态(21*20/2)。
移项后得E(x, y) -P * E(x1, y1) - (1 - P) * E(x2, y2) = 1,共有210个这样的方程组。高斯消元求解,x[0]代表E(0,0)这个状态到目标状态的期望。
注意精度。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <math.h> using namespace std ; const double eps = 1e- ; double p,mp[][] ;
int vis[][] ; double Gauss()
{
for(int i = ; i < ; i++)
{
int k ;
for(k = i ; k < ; k++)
if(fabs(mp[k][i]) > eps) break ;
for(int j = ; j <= ; j++)
swap(mp[i][j],mp[k][j]) ;
for(int j = ; j < ; j++)
{
if(i != j)
{
if(fabs(mp[j][i]) > eps)
{
double s = mp[j][i] / mp[i][i] ;
for(int k = i ; k <= ; k++)
mp[j][k] -= mp[i][k] * s ;
}
}
}
}
return mp[][]/mp[][] ;
} void pro()
{
for(int i = ; i < ; i++)
{
for(int j = ; j < i ; j ++)
{
int u = vis[i][j] ;
mp[u][u] = ;
mp[u][] = ;
int v = vis[i][max(,j-)] ;
mp[u][v] -= (-p) ;
v = vis[i][j+] ;
mp[u][v] -= p ;
}
int u = vis[i][i] ;
mp[u][u] = ;
mp[u][] = ;
int v = vis[i][max(,i-)] ;
mp[u][v] -= (-p) ;
v = vis[i+][i] ;
mp[u][v] -= p ;
}
} int main()
{ while(scanf("%lf",&p) != EOF)
{
int cnt = ;
memset(vis,-,sizeof(vis)) ;
for(int i = ; i < ; i++)
for(int j = ; j <= i ; j++)
vis[i][j] = cnt ++ ;
memset(mp,,sizeof(mp)) ;
pro() ;
printf("%.6lf\n",Gauss()) ;
}
return ;
}
2014多校第一场J题 || HDU 4870 Rating(DP || 高斯消元)的更多相关文章
- HDU 4870 Rating(高斯消元 )
HDU 4870 Rating 这是前几天多校的题目,高了好久突然听旁边的大神推出来说是可以用高斯消元,一直喊着赶快敲模板,对于从来没有接触过高斯消元的我来说根本就是一头雾水,无赖之下这几天做DP ...
- HDU 4870 Rating (高斯消元)
题目链接 2014 多校1 Problem J 题意 现在有两个账号,初始$rating$都为$0$,现在每次打分比较低的那个,如果进前$200$那么就涨$50$分,否则跌$100$分. 每一 ...
- 2014多校第一场 E 题 || HDU 4865 Peter's Hobby (DP)
题目链接 题意 : 给你两个表格,第一个表格是三种天气下出现四种湿度的可能性.第二个表格是,昨天出现的三种天气下,今天出现三种天气的可能性.然后给你这几天的湿度,告诉你第一天出现三种天气的可能性,让你 ...
- 2014多校第一场D题 || HDU 4864 Task (贪心)
题目链接 题意 : 用N台机器,M个任务,每台机器都有一个最大工作时间和等级,每个任务有一个需要工作时间和一个等级.如果机器完成一个任务要求是:机器的工作时间要大于等于任务的时间,机器的等级要大于等于 ...
- 2014多校第一场A题 || HDU 4861 Couple doubi
题目链接 题意 : 有K个球,给你一个数P,可以求出K个值,(i=1,2,...,k) : 1^i+2^i+...+(p-1)^i (mod p).然后女朋友先取,再xp取,都希望赢,如果女朋友能赢输 ...
- 2014多校第一场 I 题 || HDU 4869 Turn the pokers(费马小定理+快速幂模)
题目链接 题意 : m张牌,可以翻n次,每次翻xi张牌,问最后能得到多少种形态. 思路 :0定义为反面,1定义为正面,(一开始都是反), 对于每次翻牌操作,我们定义两个边界lb,rb,代表每次中1最少 ...
- 2019年牛客多校第一场B题Integration 数学
2019年牛客多校第一场B题 Integration 题意 给出一个公式,求值 思路 明显的化简公式题,公式是分母连乘形式,这个时候要想到拆分,那如何拆分母呢,自然是裂项,此时有很多项裂项,我们不妨从 ...
- HDU 2262 Where is the canteen 期望dp+高斯消元
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2262 Where is the canteen Time Limit: 10000/5000 MS ...
- HDU 3364 Lanterns (高斯消元)
题意:有n个灯和m个开关,每个开关控制数个灯的状态改变,给出k条询问,问使灯的状态变为询问中的状态有多少种发法. 析:同余高斯消元法,模板题,将每个开关控制每个灯列成行列式,最终状态是结果列,同余高斯 ...
随机推荐
- UIPickerView基本用法
#import "ViewController.h" #import <UIKit/UIKit.h> @interface ViewController : UIVie ...
- Silverlight自动根据屏幕分辨率进行布局
xaml: <UserControl x:Class="SLCenterLayout.MainPage" xmlns="http://schemas.microso ...
- php学习日志(4)-The mbstring extension is missing. Please check your PHP configuration错误及解决方法
在安装好wampServer后,一直没有使用phpMyAdmin,今天用了一下,phpMyAdmin显示错误:The mbstring extension is missing. Please che ...
- 使用IO流创建文件并写入数据
/* 字符流和字节流: 字节流两个基类: InputStream OutputStream 字符流两个基类: Reader Writer 既然IO流是用于操作数据的, 那么数据的最常见体现形式是:文件 ...
- ORACLE 11G 配置DG 报ORA-10458、ORA-01152、ORA-01110
操作系统: Oracle Linux Server release 5.7 数据库版本: Oracle Database 11g Enterprise Edition Release 11.2.0.3 ...
- oracle 外部表
CREATE TABLE "EXT_ENTRY_WORKFLOW" ( ), ), "CREATE_DATE" DATE, ), ), ), ), ), ), ...
- Session设置不当导致API变成单线程问题的解决
起因: 最近开发一个项目,有个接口很慢(数据库的问题),然后在执行期间,随手去点了其他功能(调用其他接口),发现不响应了.等那个很慢的接口返回结果了,这个功能才立马返回结果. 这明显是一个问题啊! ...
- [转] c和python利用setsockopt获得端口重用
假如端口被socket使用过,并且利用socket.close()来关闭连接,但此时端口还没有释放,要经过一个TIME_WAIT的过程之后才能使用.为了实现端口的马上复用,可以选择setsockopt ...
- vagrant在windows下的使用
vagrant在windows下的使用 下载安装 VirtualBox :https://www.virtualbox.org/ 下载安装 Vagrant :http://www.vagrantup. ...
- .net speed up
Ngen.exe http://www.cnblogs.com/yukaizhao/archive/2011/11/07/how-to-use-ugen.html Merge.exe Merge dl ...