1897. tank 坦克游戏
显然考虑 $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 坦克游戏的更多相关文章
- bzoj1897. tank 坦克游戏(决策单调性分治)
题目描述 有这样一款新的坦克游戏.在游戏中,你将操纵一辆坦克,在一个N×M的区域中完成一项任务.在此的区域中,将会有许多可攻击的目标,而你每摧毁这样的一个目标,就将获得与目标价值相等的分数.只有获得了 ...
- BZOJ1897 : tank 坦克游戏
设$f[i][j][k]$表示坦克位于$(i,j)$,目前打了不超过$k$个位置的最大得分. 初始值$f[1][1][k]$为在$(1,1)$射程内最大$k$个位置的分数总和. 对于每次移动,会新增一 ...
- 887C. Slava and tanks#轰炸弹坦克游戏(分析)
题目出处:http://codeforces.com/problemset/problem/877/C 题目大意:按照游戏规则,求最小炸弹使用次数 #include<iostream> u ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- Java 坦克小游戏心得
原本是闲得慌无聊才去尝试做这个项目的,因为小时候玩小霸王的游戏机,那个时候经常玩这个游戏吧,特别是喜欢那种自定义地图的模式,觉得自由度非常不错.总之关于这个游戏,想说的一大堆.鉴于能有个空闲的时间,打 ...
- java学习之坦克大战游戏
总结:由于这几天快过年比较忙然后没怎么写,写代码途中一些经验总结现在给忘记了.这次的小项目感觉比上次写的思路清楚了点.没有之前第一次写那么逻辑混乱,结构也搞的比之前的要好,添加功能比较容易.学习了之前 ...
- Java实现简易联网坦克对战小游戏
目录 介绍 本项目的Github地址 基础版本 游戏的原理, 图形界面(非重点) 游戏逻辑 网络联机 客户端连接上服务器 定义应用层协议 TankNewMsg TankMoveMsg MissileN ...
- 自制Unity小游戏TankHero-2D(2)制作敌方坦克
自制Unity小游戏TankHero-2D(2)制作敌方坦克 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm)这个游戏制作的. ...
- 自制Unity小游戏TankHero-2D(1)制作主角坦克
自制Unity小游戏TankHero-2D(1)制作主角坦克 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm)这个游戏制作的. ...
随机推荐
- 利用BeautifulSoup爬去我爱我家的租房数据
因为之前对BeautifulSoup一直不是很熟悉,刚好身边的朋友同事在找房子,就想着能不能自己写个爬虫爬一下数据,因此就写了这个爬虫.基本都是边看书边写的,不过也没什么好讲的.直接粘代码了. # c ...
- 【转】解决ajax跨域问题的5种解决方案
转自: https://blog.csdn.net/itcats_cn/article/details/82318092 什么是跨域问题?跨域问题来源于JavaScript的"同源策略& ...
- Codeforces Round #603 (Div. 2) E. Editor
E. Editor 题目链接: https://codeforces.com/contest/1263/problem/E 题目大意: 输入一个字符串S1含有‘(’ , ‘)’ , ‘R’ , ‘L’ ...
- Nginx 在 Linux 下安装与搭建集群
搭建集群图例 集群搭建图如下,为了简单一点,使用一个Nginx服务器+两个Tomcat服务器,省略数据库部分: 环境说明 Linux 为 CentOS 7.2 发行版 + Java jdk 1.8 + ...
- 前端String类型转JSON类型
在js中通过ajax获取数据后,赋值给前端树形插件zTree中的zNodes,但一直失败如图: 浏览器端报错: 于是我将zNodes变量的值直接写死,并打印这两个的值,如图 再次运行成功.浏览器控制台 ...
- 170831-关于JdbcTemplate声明式事务-操作步骤-例子
创建一个动态web工程 加入jar包 3.创建一份jdbc.properties文件 4.在spring配置文件中配置数据源 5.测试数据源: 6.配置jdbcTemplate: 7.创建Dao类 & ...
- es之java搜索文档
1:搜索文档数据(单个索引) @Test public void getSingleDocument(){ GetResponse response = client.prepareGet(" ...
- 前端进阶系列(二):css常见布局解决方案
水平居中布局 margin+定宽 <div class="parent"> <div class="child">Demo</di ...
- 关于Java协变性的思考
简而言之,如果A IS-A B,那么A[] IS-A B[]. 举例:现在有类型Person.Employee和Student.Employee 是一个(IS-A) Person,Student是一个 ...
- progress组件(进度条)
progress组件:进度条 progress组件的属性: percent:类型:number 设置百分比 (0~100) show-info:类型:布尔 在进度条右侧显示百分比 border-rad ...