HYSBZ/BZOJ 1011 [HNOI2008] 遥远的行星 - 模糊答案&暴力

来源:互联网 发布:怎么让访客网络不影响 编辑:程序博客网 时间:2024/05/16 18:15

题目描述

分析:

纯暴力。
fi 为第i个行星所受的合力 , gi 能给行星 i 施力的编号最大的行星。

(1).gi=ai

(2).fi=j=1giMiMjij=Mij=1giMjij

(3).fi+T=Mi+Tj=1gi+TMji+Tj

=Mi+T(j=1giMji+Tj+j=gi+1gi+TMji+Tj)

=Mi+T(j=1giMjijiji+Tj+j=gi+1gi+TMji+Tj)

=Mi+T(j=1gifiMiiji+Tj+j=gi+1gi+TMji+Tj)

Mi+T(fiMii12gii+T12gi+j=gi+1gi+TMji+Tj)

Solution :

O(n2)的肯定过不了,而且题目又说了是模糊答案的,那就模糊答案吧。取平均值,算众数,中位数之类的东西都可以用来估算。
为了保证不超过5%的精确度,i <=T 的暴力处理 ,其余用推出的递推式 算出。T是自己设定的一个常数。

#include<cstdio>#include<cmath>#define MAXN 100000const int T=2000;int n,M[MAXN+10],g[MAXN+10];double a,f[MAXN+10];void read(){    scanf("%d%lf",&n,&a);    for(int i=1;i<=n;i++){        scanf("%d",&M[i]);        g[i]=floor(a*i);    }}void Violent(){    for(int i=ceil(1/a);i<=T;i++){        for(int j=1;j<=g[i];j++)            f[i]+=1.0*M[i]*M[j]/(i-j);    }}void Obfuscate(){    for(int i=T+1;i<=n;i++){        int k=i-T;        double t=0;        for(int j=g[k]+1;j<=g[i];j++)            t+=1.0*M[j]/(i-j);        f[i]=1.0*M[i]*(f[k]/(1.0*M[k])*(1.0*k-g[k]/2.0)/(1.0*i-g[k]/2.0) + t);    }}int main(){    read();    Violent();    Obfuscate();    for(int i=1;i<=n;i++)        printf("%.8lf\n",f[i]);}
0 0
原创粉丝点击