Luogu P1291 [SHOI2002]百事世界杯之旅 // 易错的期望

首先有一个式子是错的

网上有个式子是f[i] = i/n * f[i] + n-i/n * f[i-1] + 1.f[i]表示现在拿到了几个明星

这个A了但是是错的。因为只要买除i-1以外的任意一个就行,所以后面的应该是frac{n-(i-1)}{n}f[i-1]

BTC大神通过倒推写出了一个正确的式子,luogu上ButterflyDew的题解也不错。

美妙输出。

#include<bits/stdc++.h>

using namespace std ;

long long n,a,b;

long long gcd(long long a,long long b){
    return b ?  gcd(b,a%b) : a;
} 

int main(){
    scanf("%lld",&n);
    b=1;
    for(int i=1;i<=n;i++){
        b = b * i / gcd (b,i);
    }
    for(int i=1;i<=n;i++){
        a += b / i;
    }
    a *= n;
//    cout<<a<<endl<<b<<endl;
    long long p = a/b;
    a %= b;
    if(a==0){
        printf("%lld
",p);
        return 0;
    }
    long long ya = a;
    a/=gcd(a,b);
    b/=gcd(ya,b);
//    cout<<p<<endl<<a<<endl<<b<<endl;
    long long len1=0,len2=0,sb = b,sp = p;
    while(sp){
        ++len1;
        sp/=10;
    }
    while(sb){
        ++len2;
        sb/=10;
    }
//    cout<<len1<<endl<<len2;
    for(int i=1;i<=len1;i++){
        printf(" ");
    }
    printf("%lld",a);
    printf("
");
    if(p!=0) printf("%lld",p);
    for(int i=1;i<=len2;i++){
        printf("-");
    }
    printf("
");
    for(int i=1;i<=len1;i++){
        printf(" ");
    }
    printf("%lld",b);
    return 0;
}

TAG : SIN_XIII ⑨

原文地址:https://www.cnblogs.com/SINXIII/p/10999041.html