设$f0[i][j][x][y][S]$表示盗贼位于$(i,j)$,守卫位于$(x,y)$,每棵苹果树苹果数量为$S$,盗贼先手时盗贼还能偷多少苹果。

设$f1[i][j][x][y][S]$表示盗贼位于$(i,j)$,守卫位于$(x,y)$,每棵苹果树苹果数量为$S$,守卫先手时盗贼还能偷多少苹果。

转移:$f0$为后继$f1$状态的最大值,$f1$为后继$f0$状态的最小值。

假设所有状态的值都是$0$,将所有状态加入队列依次进行松弛,发现值改变则继续入队列。

因为每个状态的值只有$13$种取值,所以最多入队列$13$次。

#include<cstdio>
const int N=230500,M=1048575;
char a[9][9];
int Case,n,m,ca,cnt,i,j,k,x,y,nx,ny,S,sx,sy,tx,ty,o,tmp,flag;
int id[7][8][7][8][256],apple[7][8];
int f0[N],f1[N];bool in0[N],in1[N];
int head,tail,q[M+5];
bool can[7][8];
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
int g0[N][12],g1[N][12],h0[N][12],h1[N][12];
inline int get(int x,int y){return x>>(y<<1)&3;}
inline int down(int x,int y){return x-(1<<(y<<1));}
inline void umin(int&a,int b){a>b?(a=b):0;}
inline void umax(int&a,int b){a<b?(a=b):0;}
inline void add01(int x,int y,int z){
g0[x][++g0[x][0]]=y<<1|z;
h1[y][++h1[y][0]]=x;
}
inline void add10(int x,int y){
g1[x][++g1[x][0]]=y;
h0[y][++h0[y][0]]=x;
}
inline void cal0(int x){
int old=f0[x],now=0;
for(int i=1;;i++){
int u=g0[x][i];
if(!u)break;
umax(now,f1[u>>1]+(u&1));
}
if(now!=old){
f0[x]=now;
if(!in0[x])q[tail=(tail+1)&M]=x,in0[x]=1;
}
}
inline void cal1(int x){
int old=f1[x],now=12;
for(int i=1;;i++){
int u=g1[x][i];
if(!u)break;
umin(now,f0[u]);
}
if(now!=old){
f1[x]=now;
if(!in1[x])q[tail=(tail+1)&M]=-x,in1[x]=1;
}
}
int main(){
n=5,m=6;
scanf("%d",&Case);
while(Case--){
for(i=0;i<=n+1;i++)for(j=0;j<=m+1;j++)can[i][j]=0,apple[i][j]=-1;
ca=0;
for(i=1;i<=n;i++){
scanf("%s",a[i]+1);
for(j=1;j<=m;j++){
if(a[i][j]!='#')can[i][j]=1;
if(a[i][j]=='3')apple[i][j]=ca++;
if(a[i][j]=='S')sx=i,sy=j;
if(a[i][j]=='T')tx=i,ty=j;
}
}
cnt=0;
for(i=0;i<=n+1;i++)for(j=0;j<=m+1;j++)for(x=0;x<=n+1;x++)for(y=0;y<=m+1;y++)for(S=0;S<256;S++)id[i][j][x][y][S]=0;
for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(can[i][j])
for(x=1;x<=n;x++)for(y=1;y<=m;y++)if(can[x][y]&&((x!=i)||(y!=j)))
for(S=0;S<256;S++)id[i][j][x][y][S]=++cnt;
for(i=0;i<=cnt;i++){
f0[i]=f1[i]=0;
g0[i][0]=g1[i][0]=h0[i][0]=h1[i][0]=0;
}
for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(can[i][j])
for(x=1;x<=n;x++)for(y=1;y<=m;y++)if(can[x][y]&&((x!=i)||(y!=j)))
for(S=0;S<256;S++){
o=id[i][j][x][y][S]; flag=0;
tmp=apple[i][j];
if(~tmp){
if(get(S,tmp))add01(o,id[i][j][x][y][down(S,tmp)],1);
else add01(o,o,0);
}
for(k=0;k<4;k++){
nx=i+dx[k],ny=j+dy[k];
if(!can[nx][ny]||(nx==x&&ny==y))continue;
flag=1;
tmp=apple[nx][ny];
if(~tmp){
if(get(S,tmp))add01(o,id[nx][ny][x][y][down(S,tmp)],1);
else add01(o,id[nx][ny][x][y][S],0);
}else add01(o,id[nx][ny][x][y][S],0);
}
if(!flag)add01(o,o,0); flag=0;
tmp=apple[x][y];
if(~tmp){
if(get(S,tmp))add10(o,id[i][j][x][y][down(S,tmp)]);
else add10(o,o);
}
for(k=0;k<4;k++){
nx=x+dx[k],ny=y+dy[k];
if(!can[nx][ny]||(nx==i&&ny==j))continue;
flag=1;
tmp=apple[nx][ny];
if(~tmp){
if(get(S,tmp))add10(o,id[i][j][nx][ny][down(S,tmp)]);
else add10(o,id[i][j][nx][ny][S]);
}else add10(o,id[i][j][nx][ny][S]);
}
if(!flag)add10(o,o);
}
for(i=1;i<=cnt;i++){
g0[i][g0[i][0]+1]=0;
g1[i][g1[i][0]+1]=0;
h0[i][h0[i][0]+1]=0;
h1[i][h1[i][0]+1]=0;
}
head=1,tail=cnt;
for(i=1;i<=cnt;i++){
in0[i]=0,in1[i]=1;
q[i]=-i;
}
while(head!=(tail+1)&M){
x=q[head];
head=(head+1)&M;
if(x>0){
in0[x]=0;
for(i=1;h0[x][i];i++)cal1(h0[x][i]);
}else{
x=-x;
in1[x]=0;
for(i=1;h1[x][i];i++)cal0(h1[x][i]);
}
}
printf("%d\n",f0[id[tx][ty][sx][sy][255]]);
}
return 0;
}

  

BZOJ1757 : Apple 偷苹果的更多相关文章

  1. "回复 集赞" 抢 《Apple Watch 苹果开发教程》活动开始了!!!

    "回复 集赞" 抢 <Apple Watch 苹果开发教程>活动开始了!!!   活动方式: 回复积赞 第1步:回复该帖   扫描二维码进入活动现场 第2步:召集你的小 ...

  2. php 经典的算法题-偷苹果

    有5个人偷了一堆苹果,准备在第二天分赃.晚上,有一人遛出来,把所有菜果分成5份,但是多了一个,顺手把这个扔给树上的猴了,自己先拿1/5藏了.没想到其他四人也都是这么想的,都如第一个人一样分成5份把多的 ...

  3. bzoj2100 [Usaco2010 DEC]Apple Delivery苹果贸易

    题目描述 一张P个点的无向图,C条正权路.CLJ要从Pb点(家)出发,既要去Pa1点NOI赛场拿金牌,也要去Pa2点CMO赛场拿金牌.(途中不必回家)可以先去NOI,也可以先去CMO.当然神犇CLJ肯 ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. Unity项目 - 捡苹果 Apple Picker

    项目展示 Github项目地址:Apple Picker 涉及知识 正投视图 3D场景内树与苹果的图层 记录最高分到本地 准备工作 模型制作: 基本模型创建 树叶:sphere 拉伸为椭圆形,绿色材质 ...

  6. 杂项-公司:Apple

    ylbtech-杂项-公司:Apple 苹果公司(Apple Inc. )是美国的一家高科技公司.由史蒂夫·乔布斯.斯蒂夫·沃兹尼亚克和罗·韦恩(Ron Wayne)等人于1976年4月1日创立,并命 ...

  7. [手机取证] Apple Watch取证初探

    转载文章请注明出处 1. 关于Apple Watch 苹果公司在2015年3月正式发布了智能手表Apple Watch,包括Apple Watch.Apple Watch Sport以及Apple W ...

  8. 苹果被拒的血泪史。。。(update 2015.11)

    项目提交了N此了,也审核N次了,苹果的审核机制依旧那么不急不慢.昨天刚刚又被拒了.回忆下之前的,总结一下吧. 2015.04.28 昨天被拒非常亏,app的评级是17+,但是在app展示图里有一个比较 ...

  9. 苹果App Store开发者帐户从申请,验证,到发布应用(2)

    app store付费 上面已经介绍了app store id的注册了,下面在注册基础上,介绍一下app store的付费.   在上面注册成功之后,会收到一封邮件.   1.收到邮件Thank Yo ...

随机推荐

  1. ASP.NET MVC上传文件

    最近参考网络资料,学习了ASP.NET MVC如何上传文件.最基本的,没有用jQuery等技术. 1.定义Model public class TestModel    {        [Displ ...

  2. matlab 图像设置

    Matlab画图设置线宽和字号 既然这么多人来这里看过,我就多做点注释,方便大家参考. 下边这段代码不需要特别设置,只需要在plot语句之后插入即可. %plot your figure before ...

  3. setLocale(java.util.Locale), setCharacterEncoding(java.lang.String),setContentType(java.lang.String type)

    对于setCharacterEncoding(java.lang.String),这个方法是javax.servlet.ServletRequest和javax.servlet.ServletResp ...

  4. 谷歌浏览器安装json格式化插件

    1.下载JsonView扩展程序压缩包 下载地址:https://github.com/gildas-lormeau/JSONView-for-Chrome 点击[Clone or download] ...

  5. I\O操作

    作用:读写设备上数据.硬盘文件.内存.键盘.网络等. 分类: 数据走向:输入流.输出流 数据类型:字符流(文本数据Reader或者Writer结尾) 字节流(所有类型Stream结尾) 1个字节 = ...

  6. PyTorch中ReLU的inplace

    0 - inplace 在pytorch中,nn.ReLU(inplace=True)和nn.LeakyReLU(inplace=True)中存在inplace字段.该参数的inplace=True的 ...

  7. jQuery新版本没有了Toggle事件,两个按钮分别控制隐藏显示,同时这两个按钮点击也要互斥。

    十二月没来得及整理发布,一直在草稿箱.现在已经2019年1月了... 需求大概是这样的 //XX点击事件 var flagBar = 0; $("#doNotBaseRate"). ...

  8. JustSoso笔记

    当时想了大半天,想着到底要怎么绕过MD5呢,结果还是没做出来,即使问了学长,自己还是漏了一个步骤,file=hint.php,特此笔记,又学到了个引用变量的知识 学习自 https://www.ctf ...

  9. Tableau 之一 连接数据源

    导入数据源 与各类数据源建立连接关系,是使用tableau探索分析数据的第一步,本节内容包括: 数据源类型 连接数据源 数据源类型 打开tableau,可以在左侧窗口看到连接选项,目前tableau可 ...

  10. HTTP协议详解(二)

    接着第一篇学习.... 5 头域(首部) 每个头域由一个域名,冒号(:)和域值三部分组成.域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表 ...