Problem F: 有钱的wingkou
Description
大家都知道,wingkou是个高富帅。有一天,wingkou在家里很无聊,于是他就想了一个游戏来玩。游戏是规则这样的,一开始,他往箱子里放了n部的IPhone 6s,还有m部的IPhone 6s Plus,每一次,他从箱子里拿出两部手机,假设两部手机是同型号的,那么就放入一台IPhone 6s Plus,否则就放入一台IPhone 6s,在重复了多次之后,他实在受不了,因为太累了,就放弃了。同时,他也想到了一个问题,那就是最后剩下的那部手机是IPhone 6s的概率有多大呢?聪明的wingkou当然秒解啦,所以现在他就来考考你,假设你能通过他的考验,那么你将获得wingkou版的高富帅气球一个。
Input
第一行输入一个样例数T
下面每一行输入n和m,代表放入了n台iPhone 6s和m台iPhone 6s Plus
Output
Sample Input
2
0 1
1 0
Sample Output
0.00
1.00
题解:
首先我们可以通过打表发现答案只能是0或者1,
且当n为奇数时答案为1,为偶数时答案为0,那么这道题可以解决了
打表程序
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include<map>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include<set>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf -0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
double dp[1100][1100];
int n,m;
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=0;i<=n+100;i++)
for(int j=0;j<=m+100;j++)
dp[i][j]=0;
dp[n][m]=1;
for(int i=n+m-1;i>=1;i--){
for(int j=0;j<=i;j++){
if(i!=j)
dp[j][i-j]=(double)(j*2*(i-j+1)+(i-j+1)*(i-j))/((i+1)*i)*dp[j][i-j+1]+(double)(j+2)*(j+1)/((i+1)*i)*dp[j+2][i-j-1];
else
dp[j][i-j]=(double)j*2/((i+1)*i)*dp[j][1];
}
}
printf("%.2lf\n",dp[1][0]);
}
return 0;
}
接下来我们便试着去证明一下答案的正确性
首先当n为偶数时,
每进行一轮,有三种情况,一种是一个6s,一个6p,这时6s的数目不变,依旧是偶数
一种是两个6s,这时6s的数目减2,依旧是偶数
一种是两个6p,这时6s的数目不变,依旧是偶数
综上所述,所剩的6s的数目一定为偶数,所以最后剩下的那个一定是6p
当n为奇数时,
每进行一轮,有三种情况,一种是一个6s,一个6p,这时6s的数目不变,依旧是奇数
一种是两个6s,这时6s的数目减2,依旧是奇数
一种是两个6p,这时6s的数目不变,依旧是奇数
综上所述,所剩的6s的数目一定为奇数,所以最后剩下的那个一定是6s
所以结论成立