题目描述

有这样一款新的坦克游戏。在游戏中,你将操纵一辆坦克,在一个N×M的区域中完成一项任务。在此的区域中,将会有许多可攻击的目标,而你每摧毁这样的一个目标,就将获得与目标价值相等的分数。只有获得了最高的分数,任务才算完成。同时,为了增加游戏的真实性和难度,该游戏还做了以下的限制:

1)坦克有射程r的限制。为方便计算,射程r规定为:若坦克位于(x, y)格,则它可攻击的目标(x1, y1)必须满足|x-x1|, |y-y1|∈[0, r]。

2)对坦克完成任务的时间有严格限制,规定为t秒。其中,坦克每进行一次移动都需1秒的时间,每攻击一个目标也需1秒的时间。时间一到t秒,便对此次任务进行记分。

3)坦克最初位于左上角,且移动方向只准是向右或向下,每次只允许移动一格。

在以上的限制条件下,要完成该任务便成为了一件很难事情。因此,你必须为此编写一个程序,让它助你完成这个艰巨的任务。

输入格式

第一行四个整数N、M、r、t,分别表示区域的长、宽,以及射程和完成任务时间。

接下来N行是一个N×M的矩阵,对应每个位置上目标的价值。

输出格式

输出文件仅一个数max,即该任务中可得到的最高分数。

样例

样例输入

5 5 2 7
0 5 0 0 4
0 0 0 0 2
0 0 0 0 0
0 0 0 0 0
5 0 3 0 11

样例输出

21

数据范围与提示

1≤N、M≤500,1≤r≤100,1≤t≤250。

对于20%的数据有:1≤N、M≤10。

对于60%的数据有:1≤N、M≤50,1≤r≤10。

对于80%的数据有:1≤N、M≤100,1≤r≤20。


设$f[i][j][k]$表示到$(i,j)$为止打$k$个的最大价值

注意到每步打目标的个数一定是单调不降的

证明....挂一神犇的blog

每次转移时用决策单调性分治优化

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define re register
using namespace std;
int read(){
char c=getchar(); int x=;
while(c<''||c>'') c=getchar();
while(''<=c&&c<='') x=x*+c-,c=getchar();
return x;
}
#define N 505
int cmp(int A,int B){return A>B;}
int n,m,R,T,ans,k=,a[N][N],f[][N][],h[N*N],tp,g[N],v[N];
void solve(int l,int r,int dl,int dr){
if(l>r||dl>dr) return ;
int mm=(l+r)/,dm=dl;
for(int i=dl;i<=min(mm,dr);++i)
if(v[mm]<g[mm-i]+h[i])
v[mm]=g[mm-i]+h[i],dm=i;
solve(l,mm-,dl,dm);
solve(mm+,r,dm,dr);
}
int main(){
n=read(); m=read(); R=read(); T=read();
for(re int i=;i<=n;++i)
for(re int j=;j<=m;++j)
a[i][j]=read();
for(re int i=;i<=R+;++i)
for(re int j=;j<=R+;++j)
if(a[i][j]) h[++tp]=a[i][j];
sort(h+,h+tp+,cmp); tp=min(tp,T);//注意最多取T个
for(re int i=;i<=tp;++i) f[][][i]=f[][][i-]+h[i];
int _n=max(,n-R),_m=max(,m-R);
for(re int i=;i<=_n;++i,k^=)
for(re int j=;j<=_m;++j){
int lim=T-i-j+;
if(lim<=) continue;
if(i>){
for(re int u=;u<=lim;++u) v[u]=g[u]=f[k^][j][u];
tp=;
for(re int u=max(,j-R);u<=min(m,j+R);++u)
if(a[i+R][u]) h[++tp]=a[i+R][u];
sort(h+,h+tp+,cmp);
for(re int u=;u<=tp;++u) h[u]+=h[u-];
solve(,lim,,tp);
for(re int u=;u<=lim;++u) f[k][j][u]=max(f[k][j][u],v[u]);
}
if(j>){
for(re int u=;u<=lim;++u) v[u]=g[u]=f[k][j-][u];
tp=;
for(re int u=max(,i-R);u<=min(n,i+R);++u)
if(a[u][j+R]) h[++tp]=a[u][j+R];
sort(h+,h+tp+,cmp);
for(re int u=;u<=tp;++u) h[u]+=h[u-];
solve(,lim,,tp);
for(re int u=;u<=lim;++u) f[k][j][u]=max(f[k][j][u],v[u]);
}
while(lim) ans=max(ans,f[k][j][lim--]);
}
printf("%d",ans);
return ;
}

bzoj1897. tank 坦克游戏(决策单调性分治)的更多相关文章

  1. BZOJ1897 : tank 坦克游戏

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

  2. P2877 [USACO07JAN]牛校Cow School(01分数规划+决策单调性分治)

    P2877 [USACO07JAN]牛校Cow School 01分数规划是啥(转) 决策单调性分治,可以解决(不限于)一些你知道要用斜率优化却不会写的问题 怎么证明?可以暴力打表 我们用$ask(l ...

  3. 4951: [Wf2017]Money for Nothing 决策单调性 分治

    Bzoj4951:决策单调性 分治 国际惯例题面:一句话题面:供应商出货日期为Ei,售价为Pi:用户收购截止日期为Si,收购价格为Gi.我们要求max((Si-Ej)*(Gi-Pj)).显然如果我们把 ...

  4. [NAIPC2016]Jewel Thief(决策单调性+分治)

    [NAIPC2016]Jewel Thief(决策单调性+分治) 题面 原题提交地址(题目编号H) 原题面下载地址 有\(n\)个物品,每个物品有一个体积\(w_i\)和价值\(v_i\),现在要求对 ...

  5. 1897. tank 坦克游戏

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

  6. P3515 [POI2011]Lightning Conductor(决策单调性分治)

    P3515 [POI2011]Lightning Conductor 式子可转化为:$p>=a_j-a_i+sqrt(i-j) (j<i)$ $j>i$的情况,把上式翻转即可得到 下 ...

  7. [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)

    显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...

  8. [loj6039]「雅礼集训 2017 Day5」珠宝 dp+决策单调性+分治

    https://loj.ac/problem/6039 我们设dp[i][j]表示考虑所有价值小于等于i的物品,带了j块钱的最大吸引力. 对于ci相同的物品,我们一定是从大到小选k个物品,又发现最大的 ...

  9. bzoj4518: [Sdoi2016]征途(DP+决策单调性分治优化)

    题目要求... 化简得... 显然m和sum^2是已知的,那么只要让sigma(si^2)最小,那就变成了求最小平方和的最小值,经典的决策单调性,用分治优化即可. 斜率优化忘得差不多就不写了 #inc ...

随机推荐

  1. openstack stein部署手册 7. nova-compute

    # 安装程序包 yum install -y openstack-nova-compute # 变更配置文件 cd /etc/nova mv nova.conf nova.conf.org cat & ...

  2. 【技巧】Windows 10 1809无法接收1903解决方法

    这都7月份了,Windows10 1903都升级的有一个月了,然而我的1809的系统一直找不到1903的更新. 虽说1903会有bug,但还是想体验一把.周围同事都更新了,心里还是痒痒的. 于是每天都 ...

  3. Java中数组在内存中的存放原理?

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyong0717/article/details/79165685Java中数组被实现为对象, ...

  4. 2018-08-01-weekly

    Algorithm 4. Median of Two Sorted Arrays What 两个排序数组的中位数 How 两个数组合并到同一个数组,然后进行排序取中间值即可 Key Codes cla ...

  5. Java面向对象(一) 类和对象

    一.软件开发进化史 摘自<从零开始学架构> 机器语言(1940年) 最早的软件开发使用的是“机器语言”,直接使用二进制码0和1来表示机器可以识别的指令和数据. 汇编语言(20世纪40年代) ...

  6. 【leetcode】1047. Remove All Adjacent Duplicates In String

    题目如下: Given a string S of lowercase letters, a duplicate removal consists of choosing two adjacent a ...

  7. IT 技术人需要思考的 15 个问题

    行内的人自嘲是程序猿.屌丝和码农,行外的人也经常拿IT人调侃,那么究竟是IT人没有价值,还是没有仔细思考过自身的价值? 1.搞 IT 的是屌丝.码农.程序猿? 人们提到IT人的时候,总会想到他们呆板. ...

  8. UE4使用Dll

    Part1. 创建和编译Dll VS中创建Visual C++ > Win32 Console Application 工程模板,选择Dll,并勾上”Empty Project”. 在Solut ...

  9. Linux shell 归纳之 last

    使用方法: 格式1:last -n n指定账号数量,最新前n个登陆信息(用户,终端,IP, 日期,时间和持续时间) 格式2:last -n <number of the latest accou ...

  10. yii2框架的安装&配置启动

    top:环境MacBook 1.通过composer 安装yii2 [yii2需要php的PDO和pdo_mysql扩展,需要确认已安装] a. 首先需要配置composer:我使用的是阿里云的镜像: ...