• 洛谷P2566 [SCOI2009]围豆豆(状压dp+计算几何)


    题面

    传送门

    题解

    首先要解决一个问题,就是怎么判断一个点是否在多边形内部

    从这个点向某一个方向做一条射线,如果这条射线和多边形的交点为奇数说明在多边形内,否则在多边形外

    然而有一些特殊情况,比方说一个多边形((0,0),(2,0),(2,1),(1,1),(1,2)),如果一个点((1,1))向上做射线和这个多边形有两个交点,然而这个点还是在多边形内部的

    那么我们可以通过加一些(eps)之类的来避免这种情况,具体可以看代码

    把所有的豆子状压,枚举起点((x,y)),设(f_{i,j,s})表示到了((i,j)),围住的豆子的情况为(s)的情况下的最小步数,那么最后(f_{x,y,s})就是走了一个回路之后围住豆子情况为(s)的最小步数

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define inf 0x3f3f3f3f
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int N=15,M=(1<<9)+5;
    const int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
    int f[N][N][M],vis[N][N][M],sum[M],val[N],xi[N],yi[N];
    struct node{int x,y,s;node(R int xx,R int yy,R int ss):x(xx),y(yy),s(ss){}};
    queue<node>q;char mp[N][N];
    int n,m,d,res=-2e9,lim;
    inline int get(R int x,R int y,R int xx,R int yy,R int s){
    	fp(i,0,d-1)if((x==xi[i]&&xx>xi[i]||x>xi[i]&&xx<=xi[i])&&yy>yi[i])
    		s^=(1<<i);
    	return s;
    }
    void solve(int x,int y){
    	q.push(node(x,y,0));
    	fp(i,1,n)fp(j,1,m)fp(s,0,lim-1)f[i][j][s]=inf;
    //	memset(f,0x3f,sizeof(f));
    	f[x][y][0]=0,vis[x][y][0]=1;
    	while(!q.empty()){
    		int x=q.front().x,y=q.front().y,s=q.front().s;q.pop();
    		vis[x][y][s]=0;
    //		printf("%d %d %d
    ",x,y,s);
    //		if((x<1||x>n)&&(y<1||y>m)&&(s<0||s>=lim))puts("qwq");
    		fp(k,0,3){
    			int nx=x+dx[k],ny=y+dy[k];
    			if(mp[nx][ny]!='0')continue;
    			int ns=k<2?get(x,y,nx,ny,s):s;
    			if(cmin(f[nx][ny][ns],f[x][y][s]+1)&&!vis[nx][ny][ns])
    				q.push(node(nx,ny,ns)),vis[nx][ny][ns]=1;
    		}
    	}
    	fp(i,0,lim-1)cmax(res,sum[i]-f[x][y][i]);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d%d%d",&n,&m,&d),lim=(1<<d);
    	fp(i,0,d-1)scanf("%d",&val[i]);
    	fp(i,0,lim-1)fp(j,0,d-1)if(i>>j&1)sum[i]+=val[j];
    	fp(i,1,n)scanf("%s",mp[i]+1);
    	fp(i,0,n+1)mp[i][0]=mp[i][m+1]='#';
    	fp(j,0,m+1)mp[0][j]=mp[n+1][j]='#';
    	fp(i,1,n)fp(j,1,m)
    		if(mp[i][j]>='1'&&mp[i][j]<='9')
    			xi[mp[i][j]-'1']=i,yi[mp[i][j]-'1']=j;
    	fp(i,1,n)fp(j,1,m)if(mp[i][j]=='0')solve(i,j);
    	printf("%d
    ",res);
    	return 0;
    }
    
  • 相关阅读:
    Power BI 根据用户权限动态生成导航跳转目标
    Power BI Tooltips 增强功能
    Power BI refresh error “could not load file or assembly…provided impersonation level is invalid”
    SQL 错误代码 18456
    如何使用SQL Server Integration Services从多个Excel文件读取数据
    通过表格编辑器将现有表引入Power BI数据流
    Power BI 中动态增长的柱状图
    ambari2.7.3离线安装hdp3.1.0时,ambari-hdp-1.repo中baseurl无值
    ambari 安装 cannot download file mysql-connector-java from http://8080/resource/mysql-connector-java.jar
    洛谷P4180 [BJWC2010]严格次小生成树
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10513068.html
Copyright © 2020-2023  润新知