传送门

显然考虑 $dp$,发现时间只和当前位置和攻击次数有关,设 $F[i][j][k]$ 表示当前位置为 $i,j$ ,攻击了 $k$ 次得到的最大分数

初始 $f[1][1][k]$ 为位置 $1,1$ 能打到的前 $k$ 大位置的分数和

每次移动都会多一行或多一列目标可以选择,攻击时显然优先攻击分数大的位置,因为要排序,

加上原本 $i,j,k$ 复杂度 $O(nm(T+ \log R)R)$ ,考虑优化

先考虑从 $f[i][j-1][k-t]$ 转移到 $f[i][j][k]$,设此时多打的 $t$ 个物品总价值为 $tmp[t]$

那么有 $f[i][j][k]=max(f[i][j-1][k-t]+tmp[t])$,然后我们能(并不)发现转移有单调性,即如果 $i,j,k$ 的最优决策点是 $t$

那么 $i,j,k+1$ 的最优决策点一定不小于 $t$,证明如下:

为了方便理解,我们把 $f[i][j-1][k-t]$ 时选择的数列看成一段区间,把 $tmp$ 看成另一段区间:

假设转移不单调,那么就会出现 $f[i][j][k+1]$ 的最优决策点 $t'<t$,在图上就是这个样子:

上面的是 $f[i][j][k]$ 的最优转移,下面的是 $f[i][j][k+1]$ 的最优转移

因为是最优,那么上面说明,左边的 $p$ 那一段没有右边的 $p$ 那一段的值大(不然就不是最优转移了)

但是下面的却有告诉我们,左边的 $p$ 那一段比右边的 $p+1$ 那一段的值大

然后就矛盾了,所以转移一定的单调的

然后就可以决策单调性分治把复杂度变成 $O(nm(T+R \log R))$

具体看代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=,M=;
inline bool cmp(const int &x,const int &y) { return x>y; }//从大到小排序
int n,m,S,T,a[N][N],f[N][N][M],ans;
int g[M],v[M],tmp[N*N],tot;
void solve(int ql,int qr,int l,int r)
{
if(ql>qr) return; int mid=ql+qr>>,pos=l;//pos记录决策点
for(int i=l;i<=r&&i<=mid;i++)
{
int t=g[mid-i]+tmp[i];
if(t>v[mid]) v[mid]=t,pos=i;
}
solve(ql,mid-,l,pos); solve(mid+,qr,pos,r);
}
int main()
{
memset(f,~0x3f,sizeof(f));//一开始都不合法
n=read(),m=read(),S=read(),T=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) a[i][j]=read();
for(int i=;i<=S+;i++)
for(int j=;j<=S+;j++) if(a[i][j]>) tmp[++tot]=a[i][j];
sort(tmp+,tmp+tot+,cmp); tot=min(tot,T);
f[][][]=; for(int k=;k<=tot;k++) f[][][k]=f[][][k-]+tmp[k];//初始化
int nn=max(,n-S),mm=max(,m-S);
for(int i=;i<=nn;i++)
for(int j=;j<=mm;j++)
{
int mx=T-i-j+; if(mx<=) continue;//mx是剩下的时间
if(i>)
{
for(int k=;k<=mx;k++) g[k]=v[k]=f[i-][j][k];
if(i+S<=n)
{
tot=;
for(int k=max(,j-S);k<=min(j+S,m);k++) if(a[i+S][k]>) tmp[++tot]=a[i+S][k];
sort(tmp+,tmp+tot+,cmp); for(int k=;k<=tot;k++) tmp[k]+=tmp[k-];
if(tot) solve(,mx,,tot);
}
for(int k=;k<=mx;k++) f[i][j][k]=v[k];
}
if(j>)
{
for(int k=;k<=mx;k++) g[k]=v[k]=f[i][j-][k];
if(j+S<=m)
{
tot=;
for(int k=max(,i-S);k<=min(i+S,n);k++) if(a[k][j+S]>) tmp[++tot]=a[k][j+S];
sort(tmp+,tmp+tot+,cmp); for(int k=;k<=tot;k++) tmp[k]+=tmp[k-];
if(tot) solve(,mx,,tot);
}
for(int k=;k<=mx;k++) f[i][j][k]=max(f[i][j][k],v[k]);
}
for(int k=;k<=mx;k++) ans=max(ans,f[i][j][k]);
}
printf("%d\n",ans);
return ;
}

1897. tank 坦克游戏的更多相关文章

  1. bzoj1897. tank 坦克游戏(决策单调性分治)

    题目描述 有这样一款新的坦克游戏.在游戏中,你将操纵一辆坦克,在一个N×M的区域中完成一项任务.在此的区域中,将会有许多可攻击的目标,而你每摧毁这样的一个目标,就将获得与目标价值相等的分数.只有获得了 ...

  2. BZOJ1897 : tank 坦克游戏

    设$f[i][j][k]$表示坦克位于$(i,j)$,目前打了不超过$k$个位置的最大得分. 初始值$f[1][1][k]$为在$(1,1)$射程内最大$k$个位置的分数总和. 对于每次移动,会新增一 ...

  3. 887C. Slava and tanks#轰炸弹坦克游戏(分析)

    题目出处:http://codeforces.com/problemset/problem/877/C 题目大意:按照游戏规则,求最小炸弹使用次数 #include<iostream> u ...

  4. bzoj AC倒序

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

  5. Java 坦克小游戏心得

    原本是闲得慌无聊才去尝试做这个项目的,因为小时候玩小霸王的游戏机,那个时候经常玩这个游戏吧,特别是喜欢那种自定义地图的模式,觉得自由度非常不错.总之关于这个游戏,想说的一大堆.鉴于能有个空闲的时间,打 ...

  6. java学习之坦克大战游戏

    总结:由于这几天快过年比较忙然后没怎么写,写代码途中一些经验总结现在给忘记了.这次的小项目感觉比上次写的思路清楚了点.没有之前第一次写那么逻辑混乱,结构也搞的比之前的要好,添加功能比较容易.学习了之前 ...

  7. Java实现简易联网坦克对战小游戏

    目录 介绍 本项目的Github地址 基础版本 游戏的原理, 图形界面(非重点) 游戏逻辑 网络联机 客户端连接上服务器 定义应用层协议 TankNewMsg TankMoveMsg MissileN ...

  8. 自制Unity小游戏TankHero-2D(2)制作敌方坦克

    自制Unity小游戏TankHero-2D(2)制作敌方坦克 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm)这个游戏制作的. ...

  9. 自制Unity小游戏TankHero-2D(1)制作主角坦克

    自制Unity小游戏TankHero-2D(1)制作主角坦克 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm)这个游戏制作的. ...

随机推荐

  1. 匿名函数 python内置方法(max/min/filter/map/sorted/reduce)面向过程编程

    目录 函数进阶三 1. 匿名函数 1. 什么是匿名函数 2. 匿名函数的语法 3. 能和匿名函数联用的一些方法 2. python解释器内置方法 3. 异常处理 面向过程编程 函数进阶三 1. 匿名函 ...

  2. IIS部署复盘(杂记)

    首先,230是网站服务器,231主要放到是数据库:所以在230(部署的服务器)上部署不需要部署IIS和Oracle数据库, 231呢?231是数据库服务器:百度一下数据库服务器是什么? 文档第五步: ...

  3. extjs定时器TaskRunner

    Extjs封装了一个定时器类叫TaskRunner,该类在Ext.util下,先看看其公共方法: TaskRunner( Number interval )   interval : Number ( ...

  4. CSS3画五角星和六角星

    最终想要实现的效果 一.五角星 在画五角星之前首先分析这个五角星是如何实现,由哪几个部分构成的,示意图如下: 三个顶角向上的三角形,通过设置旋转和定位相互重叠和拼接实现最终的五角星效果. 为了语义化和 ...

  5. volley简介

    究竟什么是volley呢?  在以前的开发过程中,开发app的时候,使用的东西可能包括: 1.Httpclient,HttpURLConnection 2.AsyncTask,AsyncTaskLoa ...

  6. 嵌入QQ聊天

    <a href="http://wpa.qq.com/msgrd?V=1&Uin=1178321443&Site=http://www.nanfangjiadian.c ...

  7. MySQL主从复制中replicate-ignore-db replicate-wild-ignore-table的应用

    MySQL主从复制中replicate-ignore-db replicate-wild-ignore-table的应用 replicate-ignore-dbreplicate-wild-ignor ...

  8. Vue知识整理6:JavaScript表达式

    可在vue中运用js表达式,完成数据的运算(包括三元运算).比较等操作.

  9. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_1_字符输入流_Reader类&FileRead

  10. shell脚本中执行python脚本并接收其返回值的例子

    1.在shell脚本执行python脚本时,需要通过python脚本的返回值来判断后面程序要执行的命令 例:有两个py程序  hello.py 复制代码代码如下: def main():    pri ...