看到决斗的题好兴奋,前几天刚做过类似的题。。所以很坚决地搞了这个题,但是搞了快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[n][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;
}