[胡泽聪 趣题选讲]大包子环绕宝藏-[状压dp]
Description
你有一个长方形的地图,每一个格子要么是一个障碍物,要么是一个有一定价值的宝藏,要么是一个炸弹,或者是一块空地。你的初始位置已经给出。
你每次可以走到上、下、左、右这四个相邻的格子。你不允许走出这幅地图,不允许进入有宝藏、障碍物或是炸弹的地方。你需要规划一个闭合的路线(起点和终点都必须在初始位置)来取得宝藏。注意这个路线围成的多边形中不可以包含炸弹。假设路线围成的多边形包含的所有宝藏的价值之和为v,并且你从起点到终点走了 k步(从一个格子走到旁边的格子算作一步),那么你沿该路线走一次将可以获得v-k的利润。
你的任务是规划一个不包含炸弹的闭合路线,并可获得最大的利润。
注意路线可以自交。为了确定一个格子是否在这条路线里面,请使用以下算法判断:
1.假设该点的坐标为需要判断的点为 p(i,j) ,该点不在路线上
2.从该点往任意方向作一条射线,如果与路线相交奇数次,我们就认为这个格子在这条路线里面,否则这个格子在这条路线外面。
n,m<=20。炸弹和宝藏的个数总和不超过8个,保证只有1个初始点。
Solution
本题难点其实就是判断格子是否在路线里面。(题目好良心系列)我选定的射线方向是竖直向上(当然其他方向也ok呀)。
所以,如果画出路径,所有的射线只会和横向路径相交(竖向的路径就直接忽略啦)
对于每一小段横向路径(即点(x,y)到(x,y+1)),我们记录这一小段路径的右端点。如此以保证奇偶性正确。
5 — 4 —3
| |
6 9 2
| |
7 — 8 — 1
如图,我们沿1-8寻找回路,则被记录的点有3,4,8,1。
虽然5和7没有被记录到,但这不影响9(多边形内部)和多边形外部的点的判断。
(当然,如果是记录所有横向路径的点也可以,例如记3,4,5,7,8,1;不过这就需要加些特判了)
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N=,K=;
int f[][]={{,},{,-},{,},{-,}};
int tx[],ty[],cnt,k;
int n,m,sx,sy,w[];
char mp[][];
int dp[][][<<K];
int q[**(<<K)],l,r;
int num(int x,int y,int z){return x*N*(<<K)+y*(<<K)+z;}
int getx(int c){return c/(N*(<<K));}
int gety(int c){return c/(<<K)%N;}
int getz(int c){return c%(<<K);}
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++)
{
scanf("%s",mp[i]+);
for (int j=;j<=m;j++) if (mp[i][j]=='S'){mp[i][j]='.';sx=i;sy=j;}
else if (mp[i][j]>''&&mp[i][j]<'')
{tx[mp[i][j]-'']=i;ty[mp[i][j]-'']=j;cnt++;mp[i][j]='#';}
} k=cnt;
for (int i=;i<=n;i++) for (int j=;j<=m;j++)
if (mp[i][j]=='B')
{mp[i][j]='#';tx[cnt]=i;ty[cnt]=j;cnt++;}
for (int i=;i<k;i++) scanf("%d",&w[i]); memset(dp,0x3f,sizeof(dp));
dp[sx][sy][]=;
q[]=num(sx,sy,);
l=r=;
int _x,_y,_z,zz;
while (l<=r)
{
_x=getx(q[l]);_y=gety(q[l]);_z=getz(q[l]);l++;
for (int i=;i<;i++)
{
if (_x+f[i][]<=n&&_x+f[i][]&&_y+f[i][]&&_y+f[i][]<=m&&mp[_x+f[i][]][_y+f[i][]]=='.')
{
zz=_z;
if (!i) for (int j=;j<cnt;j++) if (tx[j]>_x&&ty[j]==_y) zz^=<<j;
if (i==)
for (int j=;j<cnt;j++) if (tx[j]>_x+f[i][]&&ty[j]==_y+f[i][]) zz^=<<j;
if (dp[_x][_y][_z]+<dp[_x+f[i][]][_y+f[i][]][zz])
{
dp[_x+f[i][]][_y+f[i][]][zz]=dp[_x][_y][_z]+;
q[++r]=num(_x+f[i][],_y+f[i][],zz);
}
}
}
}
bool _is;int ans=,sum,t;
for (int i=;i<<<cnt;i++)
{
sum=;_is=;
for (int j=;j<cnt;j++)
{
t=i&(<<j);
if (j>=k&&t) _is=;
if (j<k&&t) sum+=w[j];
}
if (_is) ans=max(ans,sum-dp[sx][sy][i]);
}
cout<<ans;
}
[胡泽聪 趣题选讲]大包子环绕宝藏-[状压dp]的更多相关文章
- 【bzoj2734】集合选数(有点思维的状压dp)
题目传送门:bzoj2734 这题一个月前看的时候没什么头绪.现在一看,其实超简单. 我们对于每个在$ [1,n] $范围内的,没有因数2和3的数$ d $,将它的倍数$ 2^a 3^b d $一起处 ...
- PJ考试可能会用到的数学思维题选讲-自学教程-自学笔记
PJ考试可能会用到的数学思维题选讲 by Pleiades_Antares 是学弟学妹的讲义--然后一部分题目是我弄的一部分来源于洛谷用户@ 普及组的一些数学思维题,所以可能有点菜咯别怪我 OI中的数 ...
- 正睿OI DAY3 杂题选讲
正睿OI DAY3 杂题选讲 CodeChef MSTONES n个点,可以构造7条直线使得每个点都在直线上,找到一条直线使得上面的点最多 随机化算法,check到答案的概率为\(1/49\) \(n ...
- 2019暑期金华集训 Day6 杂题选讲
自闭集训 Day6 杂题选讲 CF round 469 E 发现一个数不可能取两次,因为1,1不如1,2. 发现不可能选一个数的正负,因为1,-1不如1,-2. hihoCoder挑战赛29 D 设\ ...
- BZOJ 2734 洛谷 3226 [HNOI2012]集合选数【状压DP】【思维题】
[题解] 思维题,看了别人的博客才会写. 写出这样的矩阵: 1,3,9,... 2,6,18,... 4,12.36,... 8,24,72,... 我们要做的就是从矩阵中选出一些数字,但是不能选相邻 ...
- 【bzoj3195】【 [Jxoi2012]奇怪的道路】另类压缩的状压dp好题
(上不了p站我要死了) 啊啊,其实想清楚了还是挺简单的. Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期 ...
- 【bzoj1087】【互不侵犯King】状压dp裸题(浅尝ACM-D)
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=54329606 向大(hei)佬(e)势力学(di ...
- QDUOJ 来自xjy的签到题(bfs+状压dp)
来自xjy的签到题 Description 爱丽丝冒险来到了红皇后一个n*n大小的花园,每个格子由'.'或'#'表示,'.'表示爱丽丝可以到达这个格子,‘#’表示爱丽丝不能到达这个格子,爱丽丝每1 ...
- 刷题总结——bzoj1725(状压dp)
题目: 题目描述 Farmer John 新买了一块长方形的牧场,这块牧场被划分成 N 行 M 列(1<=M<=12; 1<=N<=12),每一格都是一块正方形的土地. FJ ...
随机推荐
- 《图解HTTP》
第一章.了解web及网络基础 1.2 http的诞生 HTTP于1990年问世,那时候HTTP并没有作为正式的标准被建立,被称为HTTP/0.9 HTTP正式作为标准被公布是在1996年5月,版本被命 ...
- ubuntu下编译qt5
编译步骤参考: http://doc.qt.io/qt-5/linux.html 我们使用源代码和编译目录分离的编译方式, 这样避免编译主机系统和目标系统间的独立. 参考: Qt Configure ...
- oracle EBS rtf报表不能输出模板样式
1.需要定义中文的数据定义 2.缺少文件 cd $ADMIN_SCRIPTS_HOME prefs.ora 3.查看文档 文档 ID 1059712.1 (1)请求模版显示不出来 解决:模版定义中模 ...
- 【转】Spring学习---Spring IoC容器的核心原理
[原文] Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国. IoC和DI的基本概念 IoC(控制反转,英文含义:Inverse of Control)是Spr ...
- windows10下安装source insight 4.0(破解版)
1.从官网下载source insight4.0版本(不用下载,在后面已经把所有需要的文件都准备好了); 2.安装source insightt4.0; 3.使用下载好的sourceinsight4. ...
- arrayfun用法(转)
http://blog.sina.com.cn/s/blog_7cf4f4460101bnhh.html 利用arrayfun函数可以避免无谓的循环,从而大大提高代码的简介性.1.A=ARRAYFUN ...
- 如何创建只读权限oracle账户
1.创建角色 CREATE ROLE SELECT_ROLE 2.给角色分配权限 grant CREATE VIEW to SELECT_ROLE; grant CREATE SYNONYM to S ...
- January 01st, 2018 Week 01st Monday
Life's like a movie, write your own. Keep believing, keep pretending. 人生如同电影,书写自己的结局.持续相信,继续演出. Some ...
- October 17th 2017 Week 42nd Tuesday
We execuse our sloth under the pretext of difficulty. 我们常以困难为由,作为懒惰的借口. The process of my system-tra ...
- [LOJ 6029]「雅礼集训 2017 Day1」市场
[LOJ 6029] 「雅礼集训 2017 Day1」市场 题意 给定一个长度为 \(n\) 的数列(从 \(0\) 开始标号), 要求执行 \(q\) 次操作, 每次操作为如下四种操作之一: 1 l ...