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