Description

Input

第一行两个整数N和M,为矩阵的边长。 第二行一个整数D,为豆子的总个数。 第三行包含D个整数V1到VD,分别为每颗豆子的分值。 接着N行有一个N×M的字符矩阵来描述游戏矩阵状态,0表示空格,#表示障碍物。而数字1到9分别表示对应编号的豆子。

Output

仅包含一个整数,为最高可能获得的分值。

Sample Input

3 8
3
30 -100 30
00000000
010203#0
00000000

Sample Output

38

HINT

50%的数据满足1≤D≤3。
100%的数据满足1≤D≤9,1≤N, M≤10,-10000≤Vi≤10000。

这个博客有详细图片和解析

http://blog.csdn.net/Phenix_2015/article/details/50739989

问题在于如何判断一个豆子是否在多边形内。

实际上有一个很好判断的方法,那就是可以引一条水平射线,看和多边形有几个交点,有奇数个交点就在多边形内,否则在多边形外。

这样状态压缩,对于一个状态,肯定步数越少越好,然后就可以更据压缩的状态,做分层图最短路

每走一步就可以更新当前状态

但还有一种情况,在偶数个交点时也有可能被围起来。

如下图所示:

那么转移的过程中,显然水平方向的移动是不影响答案的,只有竖直方向的移动才会影响到点的位置

特殊情况把每一条线段假设成上端为开下端为闭的线段,即只有下断点与射线相交才会有用,那么这样同向的线段就只会被算一次了

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct ZYYS
{
int x,y,s;
};
const int dx[]={,,,-};
const int dy[]={,-,,};
int d,px[],py[],n,m,val[],ans;
int dist[][][],inf;
bool vis[][][];
char ss[][];
int cross(int sx,int sy,int x,int y,int s)
{int i;
int p=max(sy,y);
for (i=;i<=d;i++)
if (py[i]==p&&px[i]<x)
s^=(<<i-);
return s;
}
void spfa(int sx,int sy)
{int i,j;
queue<ZYYS>Q;
memset(dist,/,sizeof(dist));
inf=dist[][][];
memset(vis,,sizeof(vis));
Q.push((ZYYS){sx,sy,});
dist[sx][sy][]=;
while (Q.empty()==)
{
ZYYS u=Q.front();
Q.pop();
vis[u.x][u.y][u.s]=;
for (i=;i<;i++)
{
int x=u.x+dx[i],y=u.y+dy[i];
if (x<||x>n||y<||y>m) continue;
if (ss[x][y]=='#'||ss[x][y]!='') continue;
int s=u.s;
if (i<=)
s=cross(u.x,u.y,x,y,s);
if (dist[x][y][s]>dist[u.x][u.y][u.s]+)
{
dist[x][y][s]=dist[u.x][u.y][u.s]+;
if (vis[x][y][s]==)
{
vis[x][y][s]=;
Q.push((ZYYS){x,y,s});
}
}
}
}
for (i=;i<=(<<d)-;i++)
{
int res=-dist[sx][sy][i];
for (j=;j<=d;j++)
if (i&(<<j-)) res+=val[j];
ans=max(ans,res);
}
}
int main()
{int i,j;
cin>>n>>m>>d;
for (i=;i<=d;i++)
{
scanf("%d",&val[i]);
}
for (i=;i<=n;i++)
{
scanf("%s",ss[i]+);
for (j=;j<=m;j++)
{
if (ss[i][j]>''&&ss[i][j]<='')
px[ss[i][j]-'']=i,py[ss[i][j]-'']=j;
}
}
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
if (ss[i][j]=='')
{
spfa(i,j);
}
}
cout<<ans;
}

[SCOI2009]围豆豆的更多相关文章

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

    [BZOJ1294][SCOI2009]围豆豆(动态规划,状压) 题面 BZOJ 洛谷 题解 首先考虑如何判断一个点是否在一个多边形内(不一定是凸的),我们从这个点开始,朝着一个方向画一条射线,看看它 ...

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

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

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

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

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

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

  5. BZOJ1294: [SCOI2009]围豆豆Bean

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

  6. 【题解】SCOI2009围豆豆

    很久之前就很想做的一道题,一直思考到今天才下定决心看题解.这道题中,很关键的一点就在于:如何判断一个点是否在一个多边形内?其实如果计算几何基本功扎实的话,应该是可以很快给出答案的(可惜我完全不行):由 ...

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

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

  8. 【状态压缩DP】SCOI2009 围豆豆

    题目大意 洛谷链接 在一个\(N×M\)的矩阵方格内分布着\(D\)颗豆子,每颗豆有不同的分值\(V_i\).游戏者可以选择任意一个方格作为起始格,每次移动可以随意的走到相邻的四个格子,直到最终又回到 ...

  9. 【BZOJ】1294: [SCOI2009]围豆豆Bean

    题解 随机跳题真好玩 这个就是考虑我们怎么判断点在多边形内,就是点做一条射线,穿过了奇数条边 我们只需要记录一个二进制状态表示每个点的射线穿过路径的次数的奇偶性 枚举起点,然后用BFS的方式更新dp状 ...

随机推荐

  1. 如何从RxJava升级到RxJava2

    如何从RxJava升级到RxJava2. RxJava2已经推出有一年半的时间,由于之前RxJava已经在现有项目中广泛使用,而RxJava2在除了很多命名外并没有太多革新,所以相信有很多人跟我一样都 ...

  2. JavaScript(第十一天)【变量,作用域,内存】

    JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据 ...

  3. Beta开始前准备

    Beta准备 1. 讨论组长是否重选的议题和结论. 经过讨论,我们认为,经过一段时间的磨合,现任组长是不需要更换的. 2. 下一阶段需要改进完善的功能. 增加关于征信的功能,贴近选题主题 美化界面,尽 ...

  4. "未找到应用程序的“aps-environment”的权利字符串"

    1.先生成App ID,在去Provisioning里面生成新的Profile 2.删除Xcode里面原来的push profile(如果没有就不用删除)再次双击新下载的profile(mobilep ...

  5. 深入分析Java Web中的编码问题

    编码问题一直困扰着我,每次遇到乱码或者编码问题,网上一查,问题解决了,但是实际的原理并没有搞懂,每次遇到,都是什么头疼. 决定彻彻底底的一次性解决编码问题. 1.为什么要编码 计算机的基本单元是字节, ...

  6. 关于Android 7.0(API24)相机的问题汇总

    在开发Android项目的时候,我们会用到相机,有些时候只是开发一个普通的扫码,仅仅赋予一下 权限 就好了,但是有些时候是需要拍照和从相册中获取照片的.我们在Android 5.0以及5.0之前调用相 ...

  7. 服务器数据恢复方法_存储raid硬盘离线数据恢复案例

    [故障描述]某法院的一台HP-P4500的存储系统,底层是12块1TB的硬盘组的RAID.其中每6个1TB的盘一组,第一组的前面一部分组了一个RAID0+1,是存放HP-P4500嵌入式系统,接着组了 ...

  8. JAVA_SE基础——11.Java中的运算符

    在程序设计中,运算符应用得十分广泛,通过运算符可以将两个变量进行任意运算.数学中的"+"."-"."*"."/"运算符同 ...

  9. mysql中独立表空间与共享表空间之前如何切换

    环境 mysql版本:5.7.19 官方文档:(https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) 查看 ...

  10. 这次彻底理解了Object这个属性

    1.实例化Object对象 实例化Object对象的方式有两种:使用Object构造器和使用对象的字面量.例如: var person1 = { name: '李四' }; var person2 = ...