uva1639 Candy

Posted invoid

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uva1639 Candy相关的知识,希望对你有一定的参考价值。

组合数,对数。

这道题要用到20w的组合数,如果直接相乘的话,会丢失很多精度,所以用去对数的方式实现。

注意指数,因为取完一次后,还要再取一次才能发现取完,所以是(n+1)次方。

double 会爆掉,需要用long double

然后就是scanf和printf读入输出long doube会发生不可逆转的错误(dev-cpp),所以可以读入输出时候强制转换类型,或者用cin,cout(后者我感觉比较麻烦)。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<iomanip>
using namespace std;
const int maxn = 200000;

long double v1,v2,c;
long double p,p1,p2,res;
double pd,resd;
int n,kase;
long double f[maxn*2+10];

double logC(int n,int m) {
    return f[n]-f[m]-f[n-m];    
}

inline void init() {
    for(int i=1;i<=maxn*2;i++) f[i]=f[i-1]+log(i);
}

int main() {
    init();
    /*
    while(scanf("%d",&n)==1) {
        scanf("%lf",&pd);
        p=pd;
        p1=p2=1;
        res=0;
        for(int i=1;i<=n;i++) {
            c=logC(2*n-i,n);
            v1=c+(n+1)*log(p)+(n-i)*log(1-p);
            v2=c+(n+1)*log(1-p)+(n-i)*log(p);
            res+=(double) i*(exp(v1)+exp(v2));
        }
        resd=res;
        printf("Case %d: %.6lf\n",++kase,resd);
    }*/
    // 上面的代码是对的,嗯。我就想用cin,cout. 
    while(cin>>n) {
        cin>>p;
        p1=p2=1;
        res=0;
        for(int i=1;i<=n;i++) {
            c=logC(2*n-i,n);
            v1=c+(n+1)*log(p)+(n-i)*log(1-p);
            v2=c+(n+1)*log(1-p)+(n-i)*log(p);
            res+=(double) i*(exp(v1)+exp(v2));
        }
        cout << "Case "<<++kase<<": ";
        cout << setprecision(6) <<fixed<< res<<\n;
    }    
    // 明显感觉还是 cstdio大法好。 
    return 0;    
}

以上是关于uva1639 Candy的主要内容,如果未能解决你的问题,请参考以下文章

Uva1639(概率期望/对数处理避免丢失精度)

poj1639,uva1537,uvalive2099,scu1622,fzu1761 Picnic Planning (最小限制生成树)

UVA计数方法练习[3]

AGC027 A - Candy Distribution Again

[VijosP1639]机密文件 题解

poj 1639 最小k度限制生成树