2017南宁现场赛E 存档

现场时间不够,没加记忆化T了,滚cu

当时还写错了mx1,mx2的关系。。。

出场喜闻乐见有人加记忆化传参递归过。。不过似乎是用的map?

这份代码未必是正解,等到放上hdu交上去试试吧。。欢迎hack!

#include<bits/stdc++.h>  
//#pragma comment(linker, "/STACK:1024000000,1024000000")   
#include<stdio.h>  
#include<algorithm>  
#include<queue>  
#include<string.h>  
#include<iostream>  
#include<math.h>  
#include<set>  
#include<map>  
#include<vector>  
#include<iomanip>  
using namespace std;  
#define ll long long  
#define pb push_back  
#define FOR(a) for(int i=1;i<=a;i++)  
const int inf=0x3f3f3f3f;  
const int maxn=2e5+5e4+9;    
const int mod=985003;

ll r,k;double p;

double vis[2049][2049];

double work(ll qiang,ll ruo){
	if(qiang==0 && ruo==0)return 1;

	if(qiang<=2048 && ruo<=2048 && vis[qiang][ruo]){
		return vis[qiang][ruo];
	}
	ll hq=qiang>>1,hr=ruo>>1;
	if(ruo%2==1){
		vis[qiang][ruo]=p*work(hq,hr);
		return vis[qiang][ruo];
	}else if(qiang%2==1){
		if(ruo){
			double mx1=p*work(hq+1,(ruo-2)/2);
			double mx2=(1-p)*work(hq,hr);
			vis[qiang][ruo]=p*(mx1+mx2);
			return vis[qiang][ruo];
		}else{
			vis[qiang][ruo]=(1-p)*work(hq,0);
			return vis[qiang][ruo];
		}
	}
}

int main(){
	int T;scanf("%d",&T);
	while(T--){
		memset(vis,0,sizeof vis);
		scanf("%lld%lld%lf",&r,&k,&p);	//进行r轮,排名k
		ll num=1ll<<r;
		ll qiang=k-1,ruo=num-k;
		if(p<0.5)swap(qiang,ruo);
		printf("%.6lf
",work(qiang,ruo));
	}
}


原文地址:https://www.cnblogs.com/Drenight/p/8611213.html