• TC SRM 655 Div1 Level 3 题解


    TC SRM 655 Div1 Level 3 题解

    题目传送门

    dp+几何

    首先可以发现凸包是顺时针排列的一些线段构成的。我们可以预处理每一个蓝点是否都在一个线段(r[i] ightarrow r[j]),(箭头表示在凸包上的方向)的内测。

    然后蓝点就没有用了。

    然后再回想一下凸包的定义:所有点连接起来都是外凸的,且可以框住所有的点。

    然后我们像构建凸包那样来dp。

    首先钦定最下面,最靠左的点。然后将其它的极交排序。(dp_{i,j})表示当前凸包上的线段为(r[i]->r[j])的概率。

    注意:需要判断凸包的凸性!

    /*
    {
    ######################
    #       Author       #
    #        Gary        #
    #        2021        #
    ######################
    */
    #include<bits/stdc++.h>
    #define rb(a,b,c) for(int a=b;a<=c;++a)
    #define rl(a,b,c) for(int a=b;a>=c;--a)
    #define LL long long
    #define IT iterator
    #define PB push_back
    #define II(a,b) make_pair(a,b)
    #define FIR first
    #define SEC second
    #define FREO freopen("check.out","w",stdout)
    #define rep(a,b) for(int a=0;a<b;++a)
    #define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
    #define random(a) rng()%a
    #define ALL(a) a.begin(),a.end()
    #define POB pop_back
    #define ff fflush(stdout)
    #define fastio ios::sync_with_stdio(false)
    #define check_min(a,b) a=min(a,b)
    #define check_max(a,b) a=max(a,b)
    using namespace std;
    //inline int read(){
    //    int x=0;
    //    char ch=getchar();
    //    while(ch<'0'||ch>'9'){
    //        ch=getchar();
    //    }
    //    while(ch>='0'&&ch<='9'){
    //        x=(x<<1)+(x<<3)+(ch^48);
    //        ch=getchar();
    //    }
    //    return x;
    //}
    const int INF=0x3f3f3f3f;
    typedef pair<int,int> mp;
    /*}
    */
    struct vec{
    	int x,y;
    	vec (mp A){
    		x=A.FIR;
    		y=A.SEC;
    	}
    	vec (int A,int B){
    		x=A,y=B;
    	}
    	vec (){
    		
    	}
    	bool operator * (vec oth){//返回叉乘结果是否>=0 
    		return 1ll*x*oth.y>=1ll*y*oth.x;
    	}
    	vec operator - (vec oth){
    		return vec (x-oth.x,y-oth.y);
    	}
    	vec operator + (vec oth){
    		return vec(x+oth.x,y+oth.y);
    	}
    };
    bool cmp(vec A,vec B){
    	if(A.y!=B.y){
    		return A.y<B.y;
    	}
    	return A.x<B.x;
    }
    bool cmp_angle(vec A,vec B){//极角排序 
    	return (B-A)*(vec(0,0)-A); 
    }
    bool ok[120][120];
    bool ok2[120][120];
    double pro[120][120];
    double dp[120][120];
    map<mp,int> id;
    class BichromeSky{
    	public:
    	double totallyCovered(vector<int> rx,vector<int> ry,vector<int> P,vector<int> bx,vector<int> by){
    		vector<vec> r,b;
    		int n=rx.size();
    		vector<double> p(n);
    		rep(i,n){
    			p[i]=P[i]/1000.0;
    		}
    		rep(i,n){
    			r.PB(vec(II(rx[i],ry[i])));
    			id[II(rx[i],ry[i])]=i;
    		}
    		rep(i,bx.size())
    			b.PB(vec(II(bx[i],by[i])));
    		sort(ALL(r),cmp);
    		sort(ALL(b),cmp);
    		rep(i,n) rep(j,n){
    			if(j==i) continue;
    			int idi,idj;
    			idi=id[II(r[i].x,r[i].y)];
    			idj=id[II(r[j].x,r[j].y)];
    			ok[idi][idj]=true;
    			rep(k,b.size()){
    				ok[idi][idj]&=(r[i]-b[k])*(r[j]-b[k]);
    			}
    		}
    		double rest=0;
    		double pp=1.0;
    		rep(i,n){
    			if(n-i<2) break;
    			deque<vec> oth;
    			for(int j=i+1;j<n;++j) oth.PB(r[j]-r[i]);
    			sort(ALL(oth),cmp_angle);
    			oth.push_front(vec(II(0,0)));
    			oth.PB(vec(II(0,0)));
    			int sz=oth.size();
    			vector<double> thisp(sz);
    			rep(j,sz){
    				vec now=oth[j]+r[i];
    				int idd=id[II(now.x,now.y)];
    				thisp[j]=p[idd];
    			}
    			rep(j,sz)
    				for(int k=j+1;k<sz;++k){
    					dp[j][k]=0.0;
    					pro[j][k]=1.0;
    					int idj,idk;
    					vec jv,kv;
    					jv=oth[j]+r[i];
    					kv=oth[k]+r[i];
    					idj=id[II(jv.x,jv.y)];
    					idk=id[II(kv.x,kv.y)];
    					ok2[j][k]=ok[idj][idk];
    					for(int l=j+1;l<k;++l){
    						if(!((oth[j]-oth[l])*(oth[k]-oth[l]))){
    							pro[j][k]*=1.0-thisp[l];		
    						}
    					}
    				}
    			double tmp=0.0;
    			for(int j=1;j+1<sz;++j){
    				if(ok2[0][j])
    					dp[0][j]=thisp[j]*pro[0][j];	
    			}
    			rep(j,sz)
    				for(int k=j+1;k<sz;++k){
    					for(int l=k+1;l<sz;++l){
    						if(ok2[k][l]&&(oth[l]-oth[k])*(oth[j]-oth[k])){							
    							dp[k][l]+=dp[j][k]*thisp[l]*pro[k][l]; 
    						} 
    					}
    				}
    			rep(j,sz){
    				if(ok2[j][sz-1])
    			    	tmp+=dp[j][sz-1];
    			}
    			tmp*=pp;
    			rest+=tmp;
    			pp*=(1.0-thisp[0]);
    		}
    		return rest;
    	}
    };
    
  • 相关阅读:
    你所不知道的 C# 中的细节
    数据分析与数据挖掘 ---- 系列教程
    Tiny Core Linux 安装配置
    Debian 安装
    基于C#的内网穿透学习笔记(附源码)
    Layui前端框架介绍
    使用 C# 捕获进程输出
    sonar扫描——方法重构分析
    消除代码中的坏味道,编写高质量代码
    TensorFlow之张量
  • 原文地址:https://www.cnblogs.com/gary-2005/p/14224928.html
Copyright © 2020-2023  润新知