设$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. jQuery循环遍历取值

    1:循环遍历取值 var arr = new Array(); $(".plus-tag a span").each(function(i) { arr[i] = $(this). ...

  2. hash(散列函数)

    一直对哈希不太理解,今天上网搜了一下,总结出以下几点,希望可以对大家的理解有所帮助 1)概念 哈希就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列 ...

  3. Django unittest 单元测试

    这里就不再介绍单元测试的作用了. 首先单元测试的创建方式有两种,一种是app下面的test文件,另一种是自定义方式创建 方法一.使用test.py文件测试 from django.test impor ...

  4. mybatis调用oracle存储过程的几个参考例子

    首先写一个存储过程: create or replace procedure p_syn_equipment_20161205 is sqlstr ); begin --清空表 sqlstr := ' ...

  5. pptpd免radius限速、限连接+自由定制功能脚本

    因为就几个用户懒得上radius,所以手写了一个用户管理脚本. 脚本很简单,具体直接看repo吧. https://github.com/esxgx/pptpd-exscripts

  6. 配置SSL证书

    在阿里云买了SSL证书,但是访问的时候提示如下图: 这个就郁闷了,按照这个方式导入了证书,但还是不行,后来得到同事的帮助,使用这个工具 然后重启下服务器就可以了.

  7. spring security5.0源码导入idea

    资源路径:链接:https://pan.baidu.com/s/1Xep6hzyIF2a0AtFYDeO_bw提取码:6af8 1.解压源码 2.编译源码     windows下:直接双击gradl ...

  8. C#发送带附件的邮件的代码

    如下的代码是关于C#发送带附件的邮件的代码. MailMessage m = new MailMessage();m.Subject = "File attachment!";m. ...

  9. ubuntu 下php + nginx

    location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; root /home/roger/uicode/pcp_web; # # N ...

  10. menuStrip1动态添加菜单及快捷键

    public partial class FormMkTest : Form { public FormMkTest() { InitializeComponent(); } private void ...