BZOJ1757 : Apple 偷苹果
设$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 偷苹果的更多相关文章
- "回复 集赞" 抢 《Apple Watch 苹果开发教程》活动开始了!!!
"回复 集赞" 抢 <Apple Watch 苹果开发教程>活动开始了!!! 活动方式: 回复积赞 第1步:回复该帖 扫描二维码进入活动现场 第2步:召集你的小 ...
- php 经典的算法题-偷苹果
有5个人偷了一堆苹果,准备在第二天分赃.晚上,有一人遛出来,把所有菜果分成5份,但是多了一个,顺手把这个扔给树上的猴了,自己先拿1/5藏了.没想到其他四人也都是这么想的,都如第一个人一样分成5份把多的 ...
- bzoj2100 [Usaco2010 DEC]Apple Delivery苹果贸易
题目描述 一张P个点的无向图,C条正权路.CLJ要从Pb点(家)出发,既要去Pa1点NOI赛场拿金牌,也要去Pa2点CMO赛场拿金牌.(途中不必回家)可以先去NOI,也可以先去CMO.当然神犇CLJ肯 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- Unity项目 - 捡苹果 Apple Picker
项目展示 Github项目地址:Apple Picker 涉及知识 正投视图 3D场景内树与苹果的图层 记录最高分到本地 准备工作 模型制作: 基本模型创建 树叶:sphere 拉伸为椭圆形,绿色材质 ...
- 杂项-公司:Apple
ylbtech-杂项-公司:Apple 苹果公司(Apple Inc. )是美国的一家高科技公司.由史蒂夫·乔布斯.斯蒂夫·沃兹尼亚克和罗·韦恩(Ron Wayne)等人于1976年4月1日创立,并命 ...
- [手机取证] Apple Watch取证初探
转载文章请注明出处 1. 关于Apple Watch 苹果公司在2015年3月正式发布了智能手表Apple Watch,包括Apple Watch.Apple Watch Sport以及Apple W ...
- 苹果被拒的血泪史。。。(update 2015.11)
项目提交了N此了,也审核N次了,苹果的审核机制依旧那么不急不慢.昨天刚刚又被拒了.回忆下之前的,总结一下吧. 2015.04.28 昨天被拒非常亏,app的评级是17+,但是在app展示图里有一个比较 ...
- 苹果App Store开发者帐户从申请,验证,到发布应用(2)
app store付费 上面已经介绍了app store id的注册了,下面在注册基础上,介绍一下app store的付费. 在上面注册成功之后,会收到一封邮件. 1.收到邮件Thank Yo ...
随机推荐
- kai linux安装搜狗输入法以及更新源地址
需要去搜狗官网下载linux版的输入法,根据自己的系统选择多少位进行下载. 首先执行如下命令:dpkg -i 输入法包名,这时会报错,会报没有安装依赖包,这时需要执行apt-get install - ...
- es集群数据库~运维相关
一 数据同步方案 1 ES-JDBC 不能实现删除同步操作.MYSQL如果删除,ES不会删除 2 logstash-input-jdbc 能实现insert update,但是仍然不能实现删除 ...
- git本机服务器配置(三):Gitblit的安装
1. 下载 http://www.gitblit.com/ 2. 解压下载文件 3. 配置信息 3.1 需要提前配置好java jdk环境 3.2 打开data目录下的defaults.propert ...
- Linux使用CFSSL自签TLS证书
⒈安装CFSSL wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson ...
- mac配置go使用gopm下载第三方包
打开zshrc文件 vim ~/.zshrc 输入变量 export GOPATH="/Users/chennan/go" #这个自定义 export GOBIN=$GOPATH/ ...
- 嵌入式Linux学习路线
最近比较忙,对于嵌入式的相关学习一直没有很好的开展.今天也看了不少的嵌入式Linux的学习路线,也和几个工作过的朋友聊了聊,想把之后的学习过程记录下来. 自己以后想从事驱动开发这方面的工作,因为大多数 ...
- 题解 P4705 【玩游戏】
这题是真的神仙啊...居然用的 stl 来卡常? 话说 998244353 真的可以一眼 NTT ? noteskey 所以说只要推柿子就好了但是有的地方的推导根本就想不到... 我们令第 t 个答案 ...
- ubuntu 18.04 配置远程ssh/远程ftp/远程vnc登陆
18.04相比过去采用了新的桌面,配置环境稍微有一些不同了. 首先是远程登录,windows用Tera Trem连接,ip地址得自己根据实际情况来. ubuntu上,sudo apt-get inst ...
- 【Selenium】各浏览器(firefox,chrome,ie)驱动下载地址汇总
前两天使用Selenium分布式时,总抛出异常.更新成最新驱动可以解决.其中chrome异常如下, "platform": "WINDOWS" File &qu ...
- C++11 double转化为string
C++11转化double为string是一件很容易的事情. 方法: 1:使用C中的sprintf函数,这里就不说了. 2:使用std::ostringstream.这个与std::cout是一样的. ...