【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. 【chrome】"您的连接不是私密连接" 解决办法

    1.启用显示证书选项 在Chrome的地址栏中输入:chrome://flags/#show-cert-link,选择"启用",重启Chrome浏览器.  (操作过无用) 2.安装 ...

  2. ss客户端的使用

    这里假设读者已经搭建了ss服务.教程 客户端安装 客户端可以通过GitHub上搜索,这里就不写太详细了,避免文章被禁掉. 比如对于mac的用户,可以选择这个 客户端配置 点击程序图标以展开菜单栏 服务 ...

  3. [CF983D]Arkady and Rectangles[线段树+可删堆/set]

    题意 你有一个无限大的绘图板,开始颜色是\(0\) , 你将进行\(n\) 次绘图,第\(i\) 次绘图会将左下角为 \((x_1, y_1)\),右上角为\((x_2, y_2)\) 的矩形涂成颜色 ...

  4. Vue重载组件....

    v-if配合Vue.nextTick()销毁当前组件后,重新加载...

  5. 安装loadrunner11出现Microsoft Visual c++2005 sp1安装失败

    本文转至别处,网上大神多

  6. EntityFramework Core 2.x (ef core) 在迁移中自动生成数据库表和列说明

    在项目开发中有没有用过拼音首字母做列名或者接手这样的项目? 看见xmspsqb(项目审批申请表)这种表名时是否有一种无法抑制的想肛了取名的老兄的冲动? 更坑爹的是这种数据库没有文档(或者文档老旧不堪早 ...

  7. 通过blockchain_go分析区块链交易原理

    原文链接-石匠的Blog 1.背景 在去中心化的区块链中进行交易(转账)是怎么实现的呢?本篇通过blockchain_go来分析一下.需要进行交易,首先就需要有交易的双方以及他们的认证机制,其次是各自 ...

  8. PAT甲题题解-1035. Password (20)-水

    题意:给n个用户名和密码,把密码中的1改为@,0改为%,l改为L,O改为o. 让你输出需要修改密码的用户名个数,以及对应的用户名和密码,按输入的顺序.如果没有用户需要修改,则输出对应的语句,注意单复数 ...

  9. Spherical Hashing,球哈希

    1. Introduction 在传统的LSH.SSH.PCA-ITQ等哈希算法中,本质都是利用超平面对数据点进行划分,但是在D维空间中,至少需要D+1个超平面才能形成一个封闭.紧凑的区域.而球哈希方 ...

  10. Resharper简单安装及代码覆盖率的测试

    Resharper简单安装及代码覆盖率的测试 测试环境:VS 2015 专业版 一.下载Resharper 官方链接:https://www.jetbrains.com/resharper/ 点击下载 ...