【BZOJ1294】[SCOI2009]围豆豆(动态规划,状压)

题面

BZOJ

洛谷

题解

首先考虑如何判断一个点是否在一个多边形内(不一定是凸的),我们从这个点开始,朝着一个方向画一条射线,看看它和这个多边形的变相交了几次,如果是奇数次那么一定在这个多边形内,否则不在。

这个可以感性理解一下,如果在内部的话,第一次碰到就是出了这个多边形,第二次又是进来,第三次又是出去......而最后总会出去,所以是奇数次。如果不在内部的话,显然就是进去出去是两两配对的,也就是偶数次。

那么我们可以在网格上从每一个豆豆开始向右侧画一条条的射线,那么和射线交的次数决定了这个豆豆是否在内。同时,放置射线和某条边界完全重合导致的不好计算,我们可以认为我们围豆豆的边在方格中线的偏上位置,而豆豆都恰好在格子的中心,这样子计算就要求强制跨越中线才算豆豆和这条线有交点,这样子就不会有问题了。

所以这个时候我们只需要钦定一个起点,设\(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]围豆豆(动态规划,状压)的更多相关文章

  1. 洛谷P2566 [SCOI2009]围豆豆(状压dp+spfa)

    题目传送门 题解 Σ(っ °Д °;)っ 前置知识 射线法:从一点向右(其实哪边都行)水平引一条射线,若射线与路径的交点为偶数,则点不被包含,若为奇数,则被包含.(但注意存在射线与路径重合的情况) 这 ...

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

    题面 传送门 题解 首先要解决一个问题,就是怎么判断一个点是否在多边形内部 从这个点向某一个方向做一条射线,如果这条射线和多边形的交点为奇数说明在多边形内,否则在多边形外 然而有一些特殊情况,比方说一 ...

  3. [BZOJ1294][SCOI2009]围豆豆Bean 射线法+状压dp+spfa

    1294: [SCOI2009]围豆豆Bean Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 458  Solved: 305[Submit][Sta ...

  4. SCOI 2009 围豆豆(状压DP)

    SCOI 2009 围豆豆 题目描述 是不是平时在手机里玩吃豆豆游戏玩腻了呢?最近MOKIA手机上推出了一种新的围豆豆游戏,大家一起来试一试吧. 游戏的规则非常简单,在一个N×M的矩阵方格内分布着D颗 ...

  5. BZOJ1294: [SCOI2009]围豆豆Bean

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1294 状压dp,dis[s][i][j]表示从(i,j)出发围的状态是s的最短路. 然后判断一 ...

  6. bzoj1294 [SCOI2009]围豆豆

    Description Input 第一行两个整数N和M,为矩阵的边长. 第二行一个整数D,为豆子的总个数. 第三行包含D个整数V1到VD,分别为每颗豆子的分值. 接着N行有一个N×M的字符矩阵来描述 ...

  7. 【BZOJ1294】[SCOI2009]围豆豆Bean 射线法+状压DP+SPFA

    [BZOJ1294][SCOI2009]围豆豆Bean Description Input 第一行两个整数N和M,为矩阵的边长. 第二行一个整数D,为豆子的总个数. 第三行包含D个整数V1到VD,分别 ...

  8. 状态压缩动态规划 状压DP

    总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...

  9. BZOJ 1294 [SCOI2009]围豆豆Bean ——计算几何

    显然我们不可能表示出一台路径,因为实在是太复杂了. 所以我们可以记录一下路径对答案的影响,显然路径对答案影响相同的时候,答案更优,所以我们可以用影响来代替路径. 所以我们考虑状压一下所有的豆子有没有被 ...

随机推荐

  1. word导入导出自定义属性列表

    Sub ExportCustom() ' ' ExportCustom 宏 ' 导出自定义属性到custom.txt ' Dim lFileNumber As Long Dim sFilePath A ...

  2. 带你看懂大数据采集引擎之Flume&采集目录中的日志

    一.Flume的介绍: Flume由Cloudera公司开发,是一种提供高可用.高可靠.分布式海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于采集数据:同时,flum ...

  3. sql语句之表间字段值复制遇到的一些问题--基于mysql

    好久没来园子了,转眼2017已经到3月份了,前段时间一直忙没时间写博客(其实是自己懒),感觉内心好惭愧.昨天临下班前,技术老大突然对我说要改下表结构,问我能不能实现将一个表的字段值复制到另外一个表的某 ...

  4. 2017-2018-1 20155232 嵌入式C语言——时钟

    2017-2018-1 20155232 嵌入式C语言--时钟 任务: 在作业本上完成附图作业,要认真看题目要求. 提交作业截图 作弊本学期成绩清零(有雷同的,不管是给别人传答案,还是找别人要答案都清 ...

  5. 20155318 《网络攻防》 Exp9 Web基础

    20155318 <网络攻防> Exp9 Web基础 基础问题 SQL注入攻击原理,如何防御 就是通过把SQL命令插入到"Web表单递交"或"输入域名&quo ...

  6. WPF编程,通过Double Animation动态缩放控件的一种方法。

    原文:WPF编程,通过Double Animation动态缩放控件的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/art ...

  7. mapreduce 多种输入

    1.多路径输入 1)FileInputFormat.addInputPath 多次调用加载不同路径 FileInputFormat.addInputPath(job, new Path("h ...

  8. Ubuntu16.04上用源代码安装ICE

    ubuntu16.04上用源代码安装ICE

  9. Invitation Cards POJ-1511 (spfa)

    题目链接:Invitation Cards 题意: 给出一张有向图,现在要求从1到其他所有的结点的最小路径和与从所有其他结点到1的最小路径和之和. 题解: 求最小路径可以用SPFA来求解.从1到其他结 ...

  10. (3)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Consul服务治理

    Consul是注册中心,服务提供者.服务提供者.服务消费者等都要注册到Consul中,这样就可以实现服务提供者.服务消费者的隔离. 除了Consul之外,还有Eureka.Zookeeper等类似软件 ...