zoukankan      html  css  js  c++  java
  • UVA

    题面在这里!

        一开始看n<=30完全没有头绪啊。。。感觉不能二进制状压的样子qwq。

        后来想了想,状态是可以压缩成 目前图中联通块大小集合 和 我们在哪个联通块的,于是开开心心整数拆分,发现n=30的时候也只有5000多,这不是怎么暴力写都能过的复杂度吗233333。

        但后来写出来之后发现因为用了太多 vector 以及 map ,还有脸黒自带的大常数,T==100且n全是30的时候就TLE(本地测的)了 qwq。

       

        于是又离线了一波,把n一样的一起回答了(因为n一样的话状态集合就是一样的),终于是过了,130ms,跑的死慢。。。。

        看提交里 10ms 的用的直接是二进制状压,迷。。。。

        (感觉自己白写了这么多行代码,mmp)

        总结起来就是 : 不开O2少用STL  23333

    /*
        x = 2/3 * 3 + 1/3 * 1.5 + 1
    */
    #include<bits/stdc++.h>
    #define ll unsigned long long
    using namespace std;
    #define pb push_back
    const int N=7005;
    
    vector<int> g[N],ask[233];
    unordered_map<ll,int> mmp;
    int n,T,tot,a[47],m,p[47],siz[47],bg[233];
    int Ge[N][35][35],pos[N][35][35],pt[233];
    double f[N][35],ans[233];
    bool v[N][35],hav[35];
    
    int getf(int x){ return p[x]==x?x:(p[x]=getf(p[x]));}
    
    inline ll gethash(vector<int> x){
    	ll an=0;
    	for(int i:x) an=an*37ll+(ll)i;
    	return an;
    }
    
    void dfs(int x,int lef){
    	if(lef>=a[x]){
    		tot++,a[x+1]=lef;
    		for(int i=1;i<=x+1;i++) g[tot].pb(a[i]);
    		mmp[gethash(g[tot])]=tot;
    	}
    	else return;
    
    	for(int i=a[x]?a[x]:a[x]+1;i*2<=lef;i++) a[x+1]=i,dfs(x+1,lef-i);
    }
    
    inline void init(){
    	for(int i=1;i<=tot;i++) g[i].clear();
    	tot=0,mmp.clear(),memset(v,0,sizeof(v));
    
    	dfs(0,n);
    
    	for(int i=1,sz;i<=tot;i++){
    		sz=g[i].size();
    		for(int j=0;j<sz;j++)
    			for(int k=j+1,l;k<sz;k++){
    				vector<int> now=g[i];
    				now[k]+=now[j],now[j]=0;
    
    				for(l=k;l+1<sz&&now[l]>now[l+1];l++) swap(now[l],now[l+1]);
    				pos[i][j][k]=l-1;
    				for(l=j;l&&now[l]<now[l-1];l--) swap(now[l],now[l-1]);	
    
    				Ge[i][j][k]=mmp[gethash(now)];
    			}
    	}
    }
    
    void dp(int S,int P){
    	if(v[S][P]) return;
    	v[S][P]=1,f[S][P]=0;
        if(g[S].size()==1) return;
    	f[S][P]=n-1;
        
    	for(int i=0,tx,ty;i<P;i++){
    		tx=Ge[S][i][P],ty=pos[S][i][P];
    		dp(tx,ty),f[S][P]+=f[tx][ty]*g[S][i];
    	}
    
    	for(int i=g[S].size()-1,tx,ty;i>P;i--){
    		tx=Ge[S][P][i],ty=pos[S][P][i];
    		dp(tx,ty),f[S][P]+=f[tx][ty]*g[S][i];
    	}
    
    	f[S][P]/=(double)(n-g[S][P]);
    }
    
    inline void solve(){
        for(int i=1;i<=30;i++) if(hav[i]){
            n=i,init();
            for(int j=1,tx,ty;j<=T;j++) if(pt[j]==i){
                tx=mmp[gethash(ask[j])],ty=bg[j];
                dp(tx,ty),ans[j]=f[tx][ty];
            }
        }
    }
    
    int main(){
    	scanf("%d",&T);
    	for(int i=1;i<=T;i++){
    	    scanf("%d%d",&n,&m),pt[i]=n,hav[n]=1;
    	    
    	    for(int j=1;j<=n;j++) p[j]=j,siz[j]=1;
    	    for(int j=1,uu,vv;j<=m;j++){
    	        scanf("%d%d",&uu,&vv);
    	        uu=getf(uu),vv=getf(vv);
    	        if(uu!=vv) p[uu]=vv,siz[vv]+=siz[uu];
    	    }
    	    
    	    for(int j=1;j<=n;j++) if(getf(j)==j) ask[i].pb(siz[j]);
    	    sort(ask[i].begin(),ask[i].end());
    	    for(int j=0;j<ask[i].size();j++) if(ask[i][j]==siz[getf(1)]){
    	        bg[i]=j; break;
    	    }
    	}
    	
    	solve();
    	
    	for(int i=1;i<=T;i++) printf("Case %d: %.11lf
    ",i,ans[i]);
    	
    	return 0;
    }
    
  • 相关阅读:
    SQL——with as 临时表
    SQL 在数据库中查找拥有此列名的所有表
    帆软报表(finereport)鼠标悬停背景变色
    帆软报表(finereport)控件背景色更改
    帆软报表(finereport)使用Event 事件对象 (target)修改提示框样式
    微信indexOf不能使用,代替方式
    基础知识
    VUE知识点
    银行金额处理
    flex-1
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9298354.html
Copyright © 2011-2022 走看看