SCOI 2009 围豆豆

题目描述

是不是平时在手机里玩吃豆豆游戏玩腻了呢?最近MOKIA手机上推出了一种新的围豆豆游戏,大家一起来试一试吧。

游戏的规则非常简单,在一个N×M的矩阵方格内分布着D颗豆子,每颗豆有不同的分值Vi。游戏者可以选择任意一个方格作为起始格,每次移动可以随意的走到相邻的四个格子,直到最终又回到起始格。最终游戏者的得分为所有被路径围住的豆豆的分值总和减去游戏者移动的步数。矩阵中某些格子内设有障碍物,任何时刻游戏者不能进入包含障碍物或豆子的格子。游戏者可能的最低得分为0,即什么都不做。

注意路径包围的概念,即某一颗豆在路径所形成的多边形(可能是含自交的复杂多边形)的内部。

输入格式

第一行两个整数N和M,为矩阵的边长。

第二行一个整数D,为豆子的总个数。

第三行包含D个整数V1到VD,分别为每颗豆子的分值。

接着N行有一个N×M的字符矩阵来描述游戏矩阵状态,0表示空格,#表示障碍物。而数字1到9分别表示对应编号的豆子。

输出格式

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

Sample

Input

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

Output

38

Solution

令人头大的一道题

定义数组:\(f[i][j][k]\)表示当前所在点为\(i,j\)走过了\(k\)步

k就是状压中的“状态”

怎么理解k呢

每一位i表示第i颗豆子有没有被围上

0表示没有,1表示围上了

假设有3颗豆子

000都没有

001一号围上了

011一二号围上了

100三号围上了

以此类推

然后就是判断有没有被围上的方法

这个东西属实不知道

是个叫做射线定理的东西

我们从豆豆开始向右引一条射线(其实向哪一个方向都可以),如果射线与路径的交点为奇数个,那么豆豆能被围住,反之则不能

如上

证明:

给每一条线规定内外

那么每穿过一次就反转了多边形的内外

若穿过奇数次,证明又回来了,所以在内部

反之在外部

代码参考网上

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int q[11][11][1050], f[11][11], x[11], y[11], v[11], ans;
int n, m, d, dx[4] = {1,-1,0,0}, dy[4] = {0,0,1,-1}; struct haha{
int a, b, c;
}dou; int gc(int a,int b){
char t = ' ';
while(1){
scanf("%c",&t);
if (t == '#') return -1;
if (t >= '0' && t <= '9'){
x[t - '0'] = a;
y[t - '0'] = b;
return t - '0';
}
}
} queue<haha>p;
int in[11][11][1050]; inline void doit(int stx, int sty){
memset(q, 0,sizeof(q ));
memset(in, 0, sizeof(in));
q[stx][sty][0] = 0;
p.push({stx, sty, 0});
int tx,ty,tz,tq,cross;
while (!p.empty()){
dou=p.front();p.pop();
for (int dir=0;dir<4;dir++){
tx=dou.a+dx[dir];ty=dou.b+dy[dir];
if (tx<=0||ty<=0||tx>n||ty>m||f[tx][ty]!=0) continue;
tz=dou.c;tq=q[dou.a][dou.b][dou.c]-1;
if (dir<2){
cross=min(tx,dou.a);
for (int i=1;i<=d;i++){
if (x[i]!=cross||y[i]>ty) continue;
if (tz&(1<<(i-1)))
tq-=v[i];
else
tq+=v[i];
tz=tz^(1<<(i-1));
}
}
if (!in[tx][ty][tz]){
q[tx][ty][tz]=tq;
p.push({tx,ty,tz});
in[tx][ty][tz]=1;
}
}
}
for (int i=0;i<(1<<d);i++)
if (in[stx][sty][i])
ans=max(ans,q[stx][sty][i]);
} int main(){
scanf("%d%d",&n,&m);
scanf("%d",&d);
for (int i=1;i<=d;i++)
scanf("%d",&v[i]);
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
f[i][j]=gc(i,j);
}
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (f[i][j]==0)
doit(i,j);
printf("%d",ans);
}

SCOI 2009 围豆豆(状压DP)的更多相关文章

  1. SDOI 2009 学校食堂 状压dp

    这个题的关键处1 紧跟着他的bi个人 —— 由此得出任意一个状态都可以表示为 有第一个人没吃到饭做分隔的前面所有人已吃饭,并用1<<8表示之后的(包括他)的八个人的状态2 信息仍然是上一个 ...

  2. Codevs 2009 大dota英雄 2013年省队选拔赛辽宁(状压DP)

    2009 大dota英雄 2013年省队选拔赛辽宁 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 话说退役后的生活好无聊啊,以 ...

  3. CDOJ 1402 三角形棋盘上的博弈游戏 状压DP

    三角形棋盘上的博弈游戏 题目连接: http://mozhu.today/#/problem/show/1402 Description 柱爷有天上课无聊,于是和同桌卿学姐一起下一种奇特的棋: 棋盘如 ...

  4. 【[APIO/CTSC2007]动物园】状压DP

    题目测评:https://www.luogu.org/problemnew/show/P3622 题目描述 新建的圆形动物园是亚太地区的骄傲.圆形动物园坐落于太平洋的一个小岛上,包含一大圈围栏,每个围 ...

  5. UVa 1204 Fun Game (状压DP)

    题意:有一些小孩(至少两个)围成一圈,有 n 轮游戏,每一轮从某个小孩开始往左或者往右伟手帕,拿到手帕写上自己的性别(B,G),然后以后相同方向给下一个. 然后在某个小孩结束,给出 n 轮手帕上的序列 ...

  6. HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP

    题目链接:https://vjudge.net/problem/HDU-3247 Resource Archiver Time Limit: 20000/10000 MS (Java/Others)  ...

  7. NOJ 1116 哈罗哈的大披萨 【淡蓝】 [状压dp+各种优化]

    我只能说,珍爱生命,远离卡常数的题...感谢陈老师和蔡神,没有他们,,,我调一个星期都弄不出来,,,, 哈罗哈的大披萨 [淡蓝] 时间限制(普通/Java) : 1000 MS/ 3000 MS   ...

  8. BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3336  Solved: 1936[Submit][ ...

  9. nefu1109 游戏争霸赛(状压dp)

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...

随机推荐

  1. jstat监控JVM内存使用、GC回收情况

    jstat -gcutil 2388 3000 6 每隔3秒打印一次pid为2388的堆内存的使用情况,共打印6次 S0— Heap上的 Survivor space 0 区已使用空间的百分比 S1  ...

  2. 用斗地主的实例学会使用java Collections工具类

    目录 一.背景 二.概念 1.定义 2.方法 2.1.排序方法 2.2.查找/替换方法 三.斗地主实例 3.1.代码结构 3.2.常量定义 3.3.单只牌类 3.4.玩家类 3.5.主程序 四.深入理 ...

  3. Error:org.gradle.api.internal.tasks.DefaultTaskInputs$TaskInputUnionFileCollection cannot be cast to...异常处理

    这个是打开Android Studio项目报的错误提示,单纯从上面的提示还是不能太直接的知道什么问题.后来我想这个项目的Gradle版本与我当前AS使用的版本不一致,可能是这个问题. 修改build. ...

  4. Redis集群方式

    Redis有三种集群方式:主从复制,哨兵模式和集群. 1.主从复制 主从复制原理: 从服务器连接主服务器,发送SYNC命令: 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用 ...

  5. js防抖函数

    一.什么是函数防抖 概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间. 举个栗子,坐电梯的时候,如 ...

  6. CSS中的百分比(%)如何使用???

    除了height以外垂直方向上的margin-top(bottom)或者padding-top(bottom)的百分比取值都是相对于父元素的宽度 在默认的content-box盒模型下元素的width ...

  7. <OPTEE>Trusted Application结构分析

    最近又开始和Trusted Zone打起了交道,需要把Linaro开发的开源安全系统optee os移植到实验室的老板子上.不过导师要求我先开发一个应用,在普通环境和安全环境分别有一个程序,称为hos ...

  8. Elasticsearch原理入门

    这是一篇拼接贴,我是缝合怪 项目中用到了es,使用方法是挺简单的,封装了基本api以后,把查询条件封装一下传给client执行就可,但是光使用比较肤浅,研究一下原理和本质,更利于以后开发使用 扫盲贴 ...

  9. 解决Mac上打开txt文件乱码问题

    出处:https://www.jianshu.com/p/f55ddf1e9839 经常会在Mac上打开一个txt文件,发现里面的中文都是乱码,问题是在Windows和手机上看都完全是正常的,这就十分 ...

  10. nslookup使用及常用命令

    nslookup是命令行里一个常用的DNS查询工具,最常用的功能是域名解析和反向解析. 下面罗列一些常用的nslookup命令 nslookup # 进入交互模式 >域名 # 进行正向解析 &g ...