HDU 1410 PK 무림 맹주 [조합 수 + log 최적화]

4735 단어 HDU수론
PK 무림 맹주
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1438    Accepted Submission(s): 375
Problem Description
단풍나무 깃털 은 자신 이 강하 다 고 생각 하고 무림 맹주 가 되 고 싶 어 현재 무림 맹주 인 수산화동 을 찾 아 도전 한다.수산화동 은 흔 쾌히 도전 을 받 아 들 였 고, 두 사람 은 다음 달 달 보름달 이 뜨 는 밤 HDU 캠퍼스 내 세 기둥 에서 결전 을 하기 로 약속 했다.이번 PK 경 기 는 무림 의 모든 사람들 을 끌 어 들 여 관전 시 킬 수 있 을 것 이다. 그래서 그들 은 상업 운영 잠재력 이 있 는 경제 인 을 찾 았 다. 백년 에 한 번 볼 수 있 는 세기 의 전쟁 을 조직 하 라 고 했다. 두 사람 이 모두 일정한 피 를 가지 고 있다 고 가정 하면 HP1, HP2. HP1 은 단풍 의 날개 이 고 HP2 는 수산화동 이다.그들 도 일정한 공 격 력 AP1, AP2, AP1 은 단풍나무 깃털 이 고 AP2 는 수산화동 이다.공격 을 할 때 상대방 의 HP 는 자신의 공 격 력 을 감소 시킨다. 예 를 들 어 HP1 = 2 HP2 = 1 AP1 = 1 AP2 = 1, 수산화동 이 단풍나무 깃털 을 공격 할 때 단풍나무 깃털 의 HP = 2 (원래 의 HP1) - 1 (수산화동 의 AP2) = 1.현재 두 사람 은 여러 라운드 에서 대결 하고 있다. 매 라운드 단풍 의 날개 가 수산화동 을 공격 하 는 것 이 아니 라 수산화동 이 단풍 의 날 개 를 공격 하 는 것 이다.단풍나무 깃털 이 수산화동 을 이 겨 차기 무림 맹주 의 승 률 이 되 기 를 바란다.
 
Input
이 문 제 는 행동 마다 HP1, HP2, AP1, AP2 (1 & lt; = HP1, HP2, AP1, AP2 & gt; = 32767) 의 테스트 데 이 터 를 여러 그룹 으로 포함 하고 있다.
 
Output
각 조 의 데 이 터 를 한 줄 씩 출력 하여 단풍나무 깃털 이 수산화동 을 이 길 확률 의 값 (결 과 는 4 비트 소수 유지) 입 니 다.
 
Sample Input
 
   
2 1 1 1
 

Sample Output
 
   
75.0000

A能打B  a=(hp2/ap1+!!(hp2%ap1))下;

B能打A  b=(hp1/ap2+!!(hp1%ap2))下;

如果A胜,则B必然被打b下,A则可被打0~(a-1)下

 A 被打N下  且B被打死(最后一下一定是A打B)的概率为 C(b+N-1,N)*pow(0.5,b+N);

 所以A胜的概率为 sum[C(b+i-1,i)*pow(0.5,b+i)]  0<=i

又C(b+i-1,i) = C(b+i-1-1,i-1)*(b+i-1)/i;

所以 用 temp*=(b+i-1)/i 累乘的方式计算出各级C(b+i-1,i);

因为乘的太多, double精度会丢失,所以用log10()优化一下

temp += log10(b+i-1)-log10(i);【因为log(a+b)=loga+logb ,所以变为加号】

ans+=pow(10,temp)*pow(0.5,b+i) = pow(10,temp+(b+i)*log(0.5));

注:当a=0时,C(b,0)=0,所以初始temp=1,经过log优化后,temp=log10(1)


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,j,k)for(i=j;ik;i--)
#define MS(x,y)memset(x,y,sizeof(x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ll long long
#define abs(x) (x>0?x:-x)
const int INF=0x7ffffff;

int hp1,hp2,ap1,ap2;
int a,b;
int i,j,k,n,m;
double temp,ans;

int main()
{
    while(~scanf("%d%d%d%d",&hp1,&hp2,&ap1,&ap2)){
        a=hp1/ap2+!!(hp1%ap2);
        b=hp2/ap1+!!(hp2%ap1);
        temp=log10(1);
        ans=pow(0.5,b);
        for(i=1;i

좋은 웹페이지 즐겨찾기