传送门

显然考虑 $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. flask_session

    flask_session和Flask中的session相比,比较简单,省去了 secret_key 首先,导入flask_session 模块  from flask_session import ...

  2. 【BZOJ2870】最长道路

    权限题 题意 给出一棵树,点有点权,找到树上的一条路径使得路径上点的个数和其中点权最小的点的点权之积最大,输出最大值. Sol 边分治板子题啦. 边分治后对于分出来的两棵子树 , 按到左右根的最小点权 ...

  3. 【NOIP2012模拟8.20】Memory

    题目 话说某一天,CD在爬树的时候发现了树干上有一大串奇怪的符文,于是好奇的CD就从头到尾看了一遍.看完一遍以后CD觉得,最后一段文字好像很眼熟,好像在前面见过.对于CD来说,一开始看到的符文会印象特 ...

  4. 【leetcode】1146. Snapshot Array

    题目如下: Implement a SnapshotArray that supports the following interface: SnapshotArray(int length) ini ...

  5. BP神经网络设计

    1.网络层数 大部分单个隐藏层即可 2.输入层神经元个数 输入变量的个数通常都是由问题的外部描述所确定的.例如,如果有4个外部变量作为网络的输入,那么网络就有4个输入.但是,这是不是意味着输入层的神经 ...

  6. MapServer教程3

    Compiling on Unix Compiling on Win32 PHP MapScript Installation .NET MapScript Compilation IIS Setup ...

  7. [CSP-S模拟测试]:f(Trie树+二分答案+meet in middle+two pointers)

    题目传送门(内部题67) 输入格式 第一行,三个整数$n$.$k$.$p$.第二行,$n$个自然数,表示$\{a_i\}$. 输出格式 输出一行,两个自然数,表示$f(res)$.$res$. 样例 ...

  8. angular6的响应式表单

    1:在AppModule模块里面引入 ReactiveFormsModule 要使用响应式表单,就要从@angular/forms包中导入ReactiveFormsModule,并把它添加到你的NgM ...

  9. 【初识TypeScript】 配置环境后运行Hello World编译报错.

    第一次接触TypeScript,配置好环境后, 发现连编写个最基本的Hello World都报错,代码如下: const hello:string = "Hello World!" ...

  10. win10 安装了virtualBox 启动报错 rc=-5640

    刚刚安装的virtualbox 启动就弹窗报错,,但是通过找到log 发现了下面这样的一处报错: 然后搜素发现是跟win10应用程序错误,,解决办法如下: 1.到控制面板,,--程序 再次尝试,vir ...