您的位置:首页 > 其它

hdu 4870

2016-01-23 19:37 344 查看

Rating

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Special Judge

[align=left]Problem Description[/align]
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?
 

[align=left]Input[/align]
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.
 

[align=left]Output[/align]
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.
 

[align=left]Sample Input[/align]

1.000000
0.814700

 

[align=left]Sample Output[/align]

39.000000
82.181160

 

解题思路:这道题目我一开始的想法是dp,可是又感觉状态方程无法保证无后效性,所以到这里就没有思路了。。。参考了别人的思路,确实感觉自己在这方面的题目做少了。

得分必须是f(0,0)->f(0,50)->f(50,50)->...->f(950,950)->f(950,1000)。所以所求期望次数就是到一个账号到1000的期望次数加上另一个账号达到950分的期望次数。记f(i)表示分数i*50到1000分需要的期望次数。那么答案ans=f(0)*2-f(19)。也就是说两次都到1000分,然后减去一次950到1000分的期望次数。

我们可以列方程,对于i>=2的数来说,我们记xi=f(i),那么可以得到方程组xi=p*(x(i+1)+1)+(1-p)*(x(i-2)+1)。其中(0<=i<20,i为0和1时需要特别处理,x20=0)。这样我们就可以直接套高斯消元法的模板了。

其实这道题目可以用递推去算,但是表示看不懂。。

这道题目给我的启发就是:有时候往往列出的状态方程却无法保证无后效性的时候,可以考虑把所有可能的状态都列出来(如果列出的方程组有唯一解),再利用高斯消元法把每个状态的值算出来即可,类似于这道递推的问题。

AC:

<span style="font-size:10px;">#include<iostream>
#include<cstring>
using namespace std;

const int maxn = 50;
const int eps = 1e-8;
double p,A[maxn][maxn];

void build_matrix() //建立系数矩阵
{
for(int i = 0; i < 20; i++)
{
if(i == 0) A[i][i] = p;
else if(i == 1) A[i][0] = p-1;
else A[i][i-2] = p-1;

if(i != 19) A[i][i+1] = -p;
if(i != 0) A[i][i] = 1;
A[i][20] = 1;
}
}

void Gauss(int n)
{
int row = 0, col = 0,j,k,r;
while(row < n && col < n) //处理第row个方程,第col个变量
{
r = row;
for(k = row+1; k < n; k++)
{
if(fabs(A[k][col]) > fabs(A[row][col]))
r = k;
}
if(fabs(A[r][col]) > eps)
{
if(r != col)
{
for(j = col; j <= n; j++)
swap(A[r][j],A[row][j]);
}
for(k = row+1; k < n; k++)
{
double f = A[k][col]/A[row][col];
for(j = col; j <= n; j++)
A[k][j] -= f*A[row][j];
}
row++;
}
col++;
}
//回代求解过程
for(k = n-1; k >= 0; k--)
{
for(j = k+1; j < n; j++)
A[k]
-= A[j]
*A[k][j];
A[k]
/= A[k][k];
}
printf("%.6f\n",A[0]
*2-A[19]
);
}

int main()
{
while(cin>>p)
{
memset(A,0,sizeof(A));
build_matrix();
Gauss(20);
}
return 0;
}</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学