题目大意
足球点球,两个队伍轮流踢,看最后的比分。如果某一个队伍已经不可能取胜了,就提前终止比赛,比如说比赛进行到了第九局第一只队伍踢完之后变为了4-2的比分那么就没有踢下去的必要了,就提前终止比赛,如果第九局之后是3-2的比分的话,那么第二组的球员还是有必要踢下去的,因为比赛是允许平局的。
解题思路
DFS一直搜下去如果到达的预测比分的状态并且比赛结束就可以了,但是要加一个判断,就是如果比赛没有必要进行下去的时候第一只队伍和第二只队伍的得分都不要更新了,但是还是要一直搜索下去,因为判断得分只在比赛结束进行
AC代码
#include<cstdio>
#include<cstring>
#include<set>
#include<stack>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<iostream>
#include<map>
using namespace std;
const int MAXN = 200005;
typedef long long LL; //lld
int a,b;
double ans;
double chance[15];
bool goOnMatch(int x,int y,int k)
{
if( x -y >(k+1)/2 )
return false;
if(y-x>k/2)
return false;
return true;
}
void dfs(int x,int y,int k,double p)
{
if(p<1e-6)
return ;
//要注意下面的判断不只进行一次,因为达到预计的比分的话,得分的情况不止一种
if(k == 10)//当所有人员全部踢完了
{
if(x == a && y == b)//如果到达了预计的分数
ans += p;//等于所有所有到达这个分数的概率之和
return ;
}
if(!goOnMatch(x,y,10-k)) //如果比赛没有必要进行下去了
{
dfs(x,y,k+1,p); //报纸现在的比分继续搜
return ;
}
if(k%2 == 0)//第一只队伍点球
{
dfs(x+1,y,k+1,chance[k]*p);//第一只队伍得分
dfs(x,y,k+1,(1-chance[k])*p);//第一只队伍不得分
}
else //第二只队伍点球
{
dfs(x,y+1,k+1,chance[k]*p);
dfs(x,y,k+1,(1-chance[k])*p);
}
return ;
}
int main()
{
int cnt = 1;
while(scanf("%lf",&chance[0])!=EOF)
{
for(int i=1;i<5;i++)
scanf("%lf",&chance[2*i]);
for(int i=0;i<5;i++)
scanf("%lf",&chance[2*i+1]);
scanf("%d-%d",&a,&b);
ans = 0;
//下面参数分别为a的得分,b的得分,进行到了几场,进行到这个比分的概率
dfs(0,0,0,1.0);
printf("Case %d: %.2f%%\n", cnt++, 100*ans );
}
return 0;
}