您的位置:首页 > 其它

sicilyOJ 11珠海赛重现 C Unlosing Ranger V.S. Darkdeath Evilman(DP)

2014-03-30 20:55 309 查看
看到决斗的题好兴奋,前几天刚做过类似的题。。所以很坚决地搞了这个题,但是搞了快3个小时


题意:

有一个超人和怪兽, 各自有血n和m

每个回合超人先打怪兽,每次造成X1-X2之间的伤害,伤害是X1-X2之间的整数点,

且每个整数点的概率相同

然后是怪兽打超人,每次造成Y1-Y2之间的伤害,伤害的概率和超人一样

当有一方的血小于等于0就输了

然后问超人打赢怪兽的概率

果断地DP

dp[i][j][0]表示超人有i血,怪兽有j血,超人先出手的超人赢的概率

dp[i][j][1]表示超人有i血,怪兽有j血,怪兽先出手的超人赢得概率

dp[i][j][0] = ( dp[i][j-X1][1] + dp[i][j-(X1+1)][1] + ... + dp[i][j-(X2)][1] ) / (X2-X1+1);

dp[i][j][1] = ( dp[i-Y1][j][0] + dp[i-(Y1+1][j][0] + ... + dp[i-(Y1)][j][0] ) / ( Y2-Y1 + 1 );

刚开始抽了,直接暴力算,果断TLE了

后来才发现可以开一个数组

sum[i][j][1] = sum[i][0][1] + sum[i][1][1] + ... sum[i][j][1];

sum[i][j][0] = sum[0][j][0] + sum[1][j][0] + .. sum[i][j][0];

然后

dp[i][j][0] = ( sum[i][j-X1][1] - sum[i][j-X2-1][1] ) / ( X2 - X1 + 1 );

dp[i][j][1] = ( sum[i-Y1][j][0] - sum[i-Y2-1][j][1] ) / ( Y2 - Y1 + 1 );

还有细节就是要注意 j > X2, j > X1 和 j <= X1的情况

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<stack>
using namespace std;

#define inf 0x3f3f3f3f
#define eps 1e-7
#define LL long long
#define ULL unsigned long long
#define MP make_pair
#define pb push_back
#define ls i << 1
#define rs ls | 1
#define md ( ( ll[i] + rr[i] ) >> 1 )
#define mxn 1020

double dp[mxn][mxn][2];
double sum[mxn][mxn][2];
int n, m, X1, X2, Y1, Y2;

void init() {
	for( int i = 0; i <= n; ++i )
		for( int j = 0; j <= m; ++j )
			sum[i][j][0] = sum[i][j][1] = 0;
}

void solve() {
	init();
	for( int i = 1; i <= n; ++i )
		for( int j = 1; j <= m; ++j ) 
			for( int d = 0; d <= 1; ++d ) {
				if( d == 0 ) {
					int tot = ( X2 - X1 + 1 );
					if( j > X2 ) {
						dp[i][j][0] = ( sum[i][j-X1][1] - sum[i][j-X2-1][1] ) / tot;
					}
					else
						if( j > X1 ) {
							dp[i][j][0] = ( sum[i][j-X1][1] - sum[i][0][1] + X2 - j + 1 ) / tot;
						}
						else
							dp[i][j][0] = 1;
					sum[i][j][0] = sum[i][j-1][0] + dp[i][j][0];
				}
				else {
					int tot = ( Y2 - Y1 + 1 );
					if( i > Y2 ) {
						dp[i][j][1] = ( sum[i-Y1][j][0] - sum[i-Y2-1][j][0] ) / tot;
					}
					else
						if( i > Y1 ) {
							dp[i][j][1] = ( sum[i-Y1][j][0] - sum[0][j][0] ) / tot;
						}
						else
							dp[i][j][1] = 0;
					sum[i][j][1] = sum[i-1][j][1] + dp[i][j][1];
				}
			}
	printf( "%.4lf\n", dp
[m][0] );
}
int main()  {
//	freopen( "tt.txt", "r", stdin );
	int cas;
	scanf( "%d", &cas );
	while( cas-- ) {
		scanf( "%d%d%d%d%d%d", &n, &m, &X1, &X2, &Y1, &Y2 );
		solve();
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: