【BZOJ1294】[SCOI2009]围豆豆(动态规划,状压)
【BZOJ1294】[SCOI2009]围豆豆(动态规划,状压)
题面
题解
首先考虑如何判断一个点是否在一个多边形内(不一定是凸的),我们从这个点开始,朝着一个方向画一条射线,看看它和这个多边形的变相交了几次,如果是奇数次那么一定在这个多边形内,否则不在。
这个可以感性理解一下,如果在内部的话,第一次碰到就是出了这个多边形,第二次又是进来,第三次又是出去......而最后总会出去,所以是奇数次。如果不在内部的话,显然就是进去出去是两两配对的,也就是偶数次。
那么我们可以在网格上从每一个豆豆开始向右侧画一条条的射线,那么和射线交的次数决定了这个豆豆是否在内。同时,放置射线和某条边界完全重合导致的不好计算,我们可以认为我们围豆豆的边在方格中线的偏上位置,而豆豆都恰好在格子的中心,这样子计算就要求强制跨越中线才算豆豆和这条线有交点,这样子就不会有问题了。
所以这个时候我们只需要钦定一个起点,设\(f[x][y][S]\)表示当前在点\((x,y)\),并且围住了\(S\)这些豆豆的最小边界长度,最后只需要在再回到起点就可以了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long
#define MAX 15
inline int read()
{
	int x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
char g[MAX][MAX];
int n,m,D,ans=-1e9,v[MAX];
int f[MAX][MAX][1<<9];
int sum[1<<9];
bool vis[MAX][MAX][1<<9];
struct Node{int x,y,S;};
int X[MAX],Y[MAX];
int d[4][2]={1,0,-1,0,0,1,0,-1};
int Get(int fx,int fy,int x,int y,int S)
{
	for(int i=0;i<D;++i)
		if(((fx==X[i]&&x>X[i])||(fx>X[i]&&x<=X[i]))&&y>Y[i])S^=1<<i;
	return S;
}
void SPFA(int x,int y)
{
	queue<Node> Q;memset(f,63,sizeof(f));
	f[x][y][0]=0;Q.push((Node){x,y,0});
	while(!Q.empty())
	{
		int x=Q.front().x,y=Q.front().y,S=Q.front().S;Q.pop();
		for(int i=0;i<4;++i)
		{
			int xx=x+d[i][0],yy=y+d[i][1];
			if(g[xx][yy]!='0')continue;
			int SS=i<2?Get(x,y,xx,yy,S):S;
			if(f[xx][yy][SS]>f[x][y][S]+1)
			{
				f[xx][yy][SS]=f[x][y][S]+1;
				if(!vis[xx][yy][SS])vis[xx][yy][SS]=true,Q.push((Node){xx,yy,SS});
			}
		}
		vis[x][y][S]=false;
	}
	for(int i=0;i<1<<D;++i)
		ans=max(ans,sum[i]-f[x][y][i]);
}
int main()
{
	n=read();m=read();D=read();
	for(int i=0;i<D;++i)v[i]=read();
	memset(g,'#',sizeof(g));
	for(int i=1;i<=n;++i)scanf("%s",g[i]+1),g[i][m+1]='#';
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			if(g[i][j]>='1'&&g[i][j]<='9')
				X[g[i][j]-49]=i,Y[g[i][j]-49]=j;
	for(int i=0;i<1<<D;++i)
		for(int j=0;j<D;++j)
			if(i&(1<<j))sum[i]+=v[j];
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			if(g[i][j]=='0')
				SPFA(i,j);
	printf("%d\n",ans);
	return 0;
}
【BZOJ1294】[SCOI2009]围豆豆(动态规划,状压)的更多相关文章
- 洛谷P2566 [SCOI2009]围豆豆(状压dp+spfa)
		题目传送门 题解 Σ(っ °Д °;)っ 前置知识 射线法:从一点向右(其实哪边都行)水平引一条射线,若射线与路径的交点为偶数,则点不被包含,若为奇数,则被包含.(但注意存在射线与路径重合的情况) 这 ... 
- 洛谷P2566 [SCOI2009]围豆豆(状压dp+计算几何)
		题面 传送门 题解 首先要解决一个问题,就是怎么判断一个点是否在多边形内部 从这个点向某一个方向做一条射线,如果这条射线和多边形的交点为奇数说明在多边形内,否则在多边形外 然而有一些特殊情况,比方说一 ... 
- [BZOJ1294][SCOI2009]围豆豆Bean  射线法+状压dp+spfa
		1294: [SCOI2009]围豆豆Bean Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 458 Solved: 305[Submit][Sta ... 
- SCOI 2009 围豆豆(状压DP)
		SCOI 2009 围豆豆 题目描述 是不是平时在手机里玩吃豆豆游戏玩腻了呢?最近MOKIA手机上推出了一种新的围豆豆游戏,大家一起来试一试吧. 游戏的规则非常简单,在一个N×M的矩阵方格内分布着D颗 ... 
- BZOJ1294: [SCOI2009]围豆豆Bean
		题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1294 状压dp,dis[s][i][j]表示从(i,j)出发围的状态是s的最短路. 然后判断一 ... 
- bzoj1294 [SCOI2009]围豆豆
		Description Input 第一行两个整数N和M,为矩阵的边长. 第二行一个整数D,为豆子的总个数. 第三行包含D个整数V1到VD,分别为每颗豆子的分值. 接着N行有一个N×M的字符矩阵来描述 ... 
- 【BZOJ1294】[SCOI2009]围豆豆Bean 射线法+状压DP+SPFA
		[BZOJ1294][SCOI2009]围豆豆Bean Description Input 第一行两个整数N和M,为矩阵的边长. 第二行一个整数D,为豆子的总个数. 第三行包含D个整数V1到VD,分别 ... 
- 状态压缩动态规划  状压DP
		总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ... 
- BZOJ 1294 [SCOI2009]围豆豆Bean ——计算几何
		显然我们不可能表示出一台路径,因为实在是太复杂了. 所以我们可以记录一下路径对答案的影响,显然路径对答案影响相同的时候,答案更优,所以我们可以用影响来代替路径. 所以我们考虑状压一下所有的豆子有没有被 ... 
随机推荐
- [Lydsy1805月赛]quailty 算法 BZOJ5362
			分析: 题目中描述了一个二分图,让我们求最小权最大匹配,实际上其实是求n个点,在n*(n-1)/2中选n条边的权值和最小,形成一个每个点都有出边的体系,也就是基环树,(证明:因为我们需要二分图最大匹配 ... 
- 20155204 王昊《网络对抗技术》EXP2   后门原理与实践
			20155204 王昊<网络对抗技术>EXP2 后门原理与实践 一.实验内容 准备工作(试用ncat.socat) 1. 使用netcat获取主机操作Shell,cron启动. 明确目标: ... 
- 20155333 《网络对抗》Exp2 后门原理与实践
			20155333 <网络对抗>Exp2 后门原理与实践 1.例举你能想到的一个后门进入到你系统中的可能方式? 下载的软件中捆绑有后门: 浏览的网页或其上的小广告: 有些网页会自动安装软件. ... 
- Android开发——为EditText添加烟花效果的实现
			)什么时候发射烟花:监听EditText的文字改变,获取文字数量的变化以确定风的方向,还有获取光标的位置确定爆炸的位置.光标的位置没有具体的方法确定坐标,要通过反射自己计算. 2. 主要实现类 库里 ... 
- JavaEE笔记(十三)
			#单一职责原则 一个类只做一件事 #开闭原则 拓展开,修改源码闭 #动态代理 1 基于接口的方式 jdk的动动代理2 基于类的方式 cglib的代理 #SSH整合 1.spring(容器) 1& ... 
- [CF1010E]Store[kd-tree]
			题意 有一个长方体,不知道它的位置,给出 \(n\) 个一定在长方体内的点和 \(m\) 个一定不在的点,有 \(k\) 次询问,每次询问一个点是否 在.不在.不确定 在长方体内. \(n\leq 1 ... 
- [UOJ#268]. 【清华集训2016】数据交互[动态dp+可删堆维护最长链]
			题意 给出 \(n\) 个点的树,每个时刻可能出现一条路径 \(A_i\) 或者之前出现的某条路径 \(A_i\) 消失,每条路径有一个权值,求出在每个时刻过后能够找到的权值最大的路径(指所有和该路径 ... 
- Security7:管理SQL Server Agent的权限
			SQL Server Agent对象包括警报(Alert),操作员(Operator),Job,调度(Schedule)和代理(Proxy),SQL Server使用msdb系统数据库管理Agent ... 
- ECS centos7 使用外部邮件服务商的465加密端口
			ECS centos7 使用外部邮件服务商的465加密端口发送邮件. 1.修改/etc/mail.rc 文件中添加以下的 set smtp="smtps://smtp.163.com:465 ... 
- Oracle实用地址
			1.详细安装教程 https://jingyan.baidu.com/article/3c48dd34be2a32e10be35881.html 
