zoukankan      html  css  js  c++  java
  • [BJOI2014]想法(随机算法,神奇思路,拓扑排序)

    对于这种随机数据或者随机算法的题……

    都是神仙题吧。

    要求的就是对每个点前 (m) 个点中有多少个可以到达它。

    由于评分方式这么奇怪,不妨考虑随机。

    随机 127 次(可以选别的数,够多而且不 T 就行),每次给前 (m) 个数随机赋值,然后拓扑求出能到达每个点的最小值。

    可能脸黑,所以多跑几次取平均数。最后每个点的平均最小值就可以看成真的期望最小值。

    有一个结论:([0,v]) 中取 (x) 个数,最小值的期望值是 (frac{v}{x+1})

    所以就能算出每个点的最小值由多少个数取得了。也就是答案。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2000200;
    #define FOR(i,a,b) for(int i=(a);i<=(b);i++)
    #define ROF(i,a,b) for(int i=(a);i>=(b);i--)
    #define MEM(x,v) memset(x,v,sizeof(x))
    inline int read(){
        int x=0,f=0;char ch=getchar();
        while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
        while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return f?-x:x;
    }
    int n,m,mn[maxn],pre[maxn][2];
    double sum[maxn];
    int main(){
    	srand(20050818);
    	n=read();m=read();
    	FOR(i,1,n-m){
    		int x=read(),y=read();
    		pre[m+i][0]=x;
    		pre[m+i][1]=y;
    	}
    	FOR(i,1,127){
    		FOR(j,1,m) mn[j]=rand();
    		FOR(j,m+1,n) mn[j]=min(mn[pre[j][0]],mn[pre[j][1]]);
    		FOR(j,1,n) sum[j]+=mn[j]/127.0;
    	}
    	FOR(j,m+1,n) printf("%.0lf
    ",RAND_MAX/sum[j]-1);
    }
    
  • 相关阅读:
    DTO vs. Assembly(转载)
    DDD:整理了一些关于验证方面的文章
    幸福框架:模块化开发
    .NET:异常以及异常处理框架探析(转载)
    Azure 基础:Queue Storage
    Azure 基础:File Storage
    Azure 基础:Blob Storage
    Azure 基础:Table storage
    用 IIS 搭建 mercurial server
    Azure 基础:使用 powershell 创建虚拟网络
  • 原文地址:https://www.cnblogs.com/1000Suns/p/11295973.html
Copyright © 2011-2022 走看看