设$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. Linux 日志文件管理——限制大小

    设计思路: 1 用一个INI配置文件管理日志目录,日志文件限制的大小,特殊的日志名,特殊日志的大小限制. 2 读取INI文件中的所有信息:每一个日志目录对应的大小限制,每一个特殊日志对应的大小限制.如 ...

  2. Luogu CF451E Devu and Flowers 题解报告

    题目传送门 [题目大意] 有n种颜色的花,第i种颜色的花有a[i]朵,从这些花中选m朵出来,问有多少种方案?答案对109+7取模 [思路分析] 这是一个多重集的组合数问题,答案就是:$$C_{n+m- ...

  3. C# 解析torrent文件

    基础知识: torrent文件信息存储格式: bencoding是一种以简洁格式指定和组织数据的方法.支持下列类型:字节串.整数.列表和字典. 1 字符串存储格式:  <字符串的长度>:& ...

  4. mvc RedirectToAction、mobile 重定向地址栏未改变

    @using (Html.BeginForm("actionName", "controllerName", FormMethod.Post, new { da ...

  5. 2018-2019 20165221 网络对抗 Exp5 MSF基础

    2018-2019 20165221 网络对抗 Exp5 MSF基础 实践内容: 重点掌握metassploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个主动攻击实践,如ms0 ...

  6. python 识别图片文字

    今天群里有兄弟问如何把图片的文字给识别出来 对于python来说这不是小菜一碟吗,于是乎让pupilheart狠狠的吹了一波(哈哈,竟然没懂),下面将整个实现过程给大家实现下: 方法一:自己搞定ORC ...

  7. 什么时候Python的List,Tuple最后一个Item后面要加上一个逗号

    为什么看Python的代码,有时候会在数据结构的最后一项末尾加上逗号.直接来看,这个逗号很多余. 根据PEP81的解释: Trailing commas are usually optional, e ...

  8. 【intern】最长公共子串、编辑距离、KMP 等

    这可能是一个很长的blog…… # from https://blog.csdn.net/justheretobe/article/details/51764587 #!/usr/bin/env py ...

  9. 关于CSRF

    CSRF介绍 CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF ...

  10. js逗号表达式

    在js中的某些场景,","是一种运算符号,只不过他的优先级要低于普通的原酸符,在变量声明或者return中,经常看到逗号表达式. 声明变量: var a=1,b=2,c=3; co ...