zoukankan      html  css  js  c++  java
  • hdu3681 Prison Break

    二分电池容量。

    至于检查答案是否合法,我们注意到有用的点只有 F,G,Y,其他的点都是无用的。这三种点加起来最多 16 个(the sum of energy pools and power switches is less than 15)。我们就可以在图中找这三种点,对他们状压。

    具体地,令 (f(i,s)) 表示当前点为 (i),其他点的经过状态为 (s)(状态压缩)的最大剩余能量,则有 (f(j,scup{j})=max{f(i,s)-operatorname{dis}(i,j)})(operatorname{dis}(i,j)) 表示点 (i) 到点 (j) 的距离,用 bfs 预处理。我们初始化将所有 (f(i,s)) 赋为 (-1)(f(x,{x})=mid)(x) 为起点)。在 dp 过程中如果发现当前枚举的 (s) 包含了所有的 Y 点且 (f(i,s)) 不为 (-1),说明能够有一种方案使得所有 Y 点都被经过,直接 return true

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=15,nxt[4][2]={0,1,1,0,0,-1,-1,0};
    int dp[N+10][(1<<N)+10];
    int n,m,dis[N*N+10][N*N+10];
    char s[N+10][N+10];
    bool vis[N+10][N+10];
    
    struct node
    {
    	int x,y,s;
    	node(int x,int y,int s) : x(x),y(y),s(s) {}
    	node() {}
    }p[N+10],que[N+10];
    int h=1,t=0;
    int bfs(int x,int y) // point x  to  point y
    {
    	memset(que,0,sizeof(que));
    	h=1;t=0;
    	memset(vis,0,sizeof(vis));
    	que[++t]=node(p[x].x,p[x].y,0);
    	vis[p[x].x][p[x].y]=1;
    	while(h<=t)
    	{
    		node head=que[h++];
    		if(head.x==p[y].x && head.y==p[y].y) return /*(puts("LHTDULIU"),*/head.s;
    		for(int i=0;i<4;i++)
    		{
    			int tx=head.x+nxt[i][0],ty=head.y+nxt[i][1];
    			if(vis[tx][ty] || s[tx][ty]=='D' || 
    			tx<1 || tx>n || ty<1 || ty>m) continue;
    			que[++t]=node(tx,ty,head.s+1); 
    			vis[tx][ty]=1;
    		}
    	}
    	return -1;
    }
    int st,cnt=0,ac=0;
    bool check(int en) // en:middle(energy)
    {
    	memset(dp,-1,sizeof(dp));
    	dp[st][1<<(st-1)]=en;
    	int all_state=1<<cnt; 
    	for(int sta=0;sta<all_state;sta++)
    	{
    		for(int i=1;i<=cnt;i++) //i:from
    		{
    			if(!(sta&(1<<(i-1)))) continue;
    			if(dp[i][sta]==-1) continue;
    			if((sta&ac)==ac) return true;
    			for(int j=1;j<=cnt;j++)
    			{
    				if(sta&(1<<(j-1))) continue;
    				if(dis[i][j]==-1) continue;
    				if(dp[i][sta]<dis[i][j]) continue;
    				int zzt=sta|(1<<(j-1)); 
    				dp[j][zzt]=max(dp[j][zzt],dp[i][sta]-dis[i][j]);
    				if(s[p[j].x][p[j].y]=='G') dp[j][zzt]=en;
    			}
    		}
    	}
    	return false; 
    }
    int main()
    {
    	while(~scanf("%d %d",&n,&m))
    	{
    		if(n==0 && m==0) break;
    		cnt=0;
    		ac=0;
    		for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
    		for(int i=1;i<=n;i++)
    		{
    			for(int j=1;j<=m;j++)
    			{ 
    				if(s[i][j]=='G')
    				{
    					p[++cnt]=node(i,j,0);
    				}
    				else if(s[i][j]=='F')
    				{
    					st=++cnt;
    					p[cnt]=node(i,j,0);
    				}
    				else if(s[i][j]=='Y')
    				{
    					cnt++;
    					ac|=(1<<(cnt-1));
    					p[cnt]=node(i,j,0);
    				}
    			}
    		}
    		memset(dp,-1,sizeof(dp));
    		memset(dis,-1,sizeof(dis));
    		for(int i=1;i<=cnt;i++)
    			for(int j=1;j<=cnt;j++)
    				dis[i][j]=dis[j][i]=bfs(i,j);
    		int l=1,r=10000,ans=-1;
    		while(l<=r)
    		{
    			int mid=(l+r)/2;
    			if(check(mid))
    			{
    				ans=mid;
    				r=mid-1;
    			}
    			else l=mid+1;
    		}
    		printf("%d",ans);
    		putchar('
    ');
    	}
    	return 0;
    }       
    /*
    5 5
    GDDSS
    SSSFS
    SYGYS
    SGSYS
    SSYSS
    5 5
    GDDSS
    SSSFS
    SYGYS
    SGSYS
    SSYSS
    5 5
    GDDSS
    SSSFS
    SYGYS
    SGSYS
    SSYSS
    0 0
    */
    
  • 相关阅读:
    2.12 使用@DataProvider
    2.11 webdriver中使用 FileUtils ()
    Xcode8 添加PCH文件
    The app icon set "AppIcon" has an unassigned child告警
    Launch Image
    iOS App图标和启动画面尺寸
    iPhone屏幕尺寸、分辨率及适配
    Xcode下载失败 使用已购项目页面再试一次
    could not find developer disk image
    NSDate与 NSString 、long long类型的相互转化
  • 原文地址:https://www.cnblogs.com/juruo-zzt/p/13908190.html
Copyright © 2011-2022 走看看