博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【DP】[Dota1001]地精工程师(GoblinTech)
阅读量:5341 次
发布时间:2019-06-15

本文共 2210 字,大约阅读时间需要 7 分钟。

描述

地精工程师的主要工作就是埋炸弹……

在一个M*N的矩形土地上,会有许多的小兵侵入,这些小兵都是钱啊,地精工程师怎能放弃这个刷钱的机会?于是,地精工程师决定埋一个遥控炸弹,等小兵都站好再引爆。
地精工程师的炸弹可以轰掉一个矩形区域,并收到所有这个矩形区域中小兵的钱。
有的小兵是魔法师……炸掉这个小兵可以让得到的钱乘2,如果炸掉多个这样的小兵,得到的钱就是原来的2^x倍(x为炸掉魔法师的个数)
地精工程师想知道,他最多能得到多少钱?

输入

第一行,两个数M,N

接下来M行N列的矩阵,表示炸掉每个位置上的小兵的钱
接下来一个数T
接下来T行,每行两个数x,y,表示位于x,y的小兵是魔法师

输出

一个数,表示最多得到多少钱

样例输入

 

样例输出

6

提示

M,N<=100

T<=10
矩阵中的数在[-500,500]之间

【Solution】

这是一个最优子矩阵的变形,其中的矩阵价值是可变的,所以我们需要在原来的方程上多加一维。

(Zip后)F[i,j]表示前i个数中已经选了j个魔法兵所获得的最大金钱。B[i]存储每个格子的魔法兵数目。

F[i,j]←max{((F[i-1,j-b[i]]/2j-b[i])+a[i])*2j,a[i]*2b[i]}

不好意思,我的程序只能通过45%的测试点,其他都WA了…等要来数据再调吧…让人纠结啊。

【Code】

 
1: Program GoblinTech(input,output);
2:   var F:array[0..100,-10..10]of int64;
3:       a:array[1..100,1..100]of longint;
4:       Magic:array[1..100,1..100]of boolean;
5:       aa,b,bb:array[0..100]of longint;
6:       up,down,i,t,j,n,m,x,y:longint;
7:       ans:int64;
8:   Function max(a,b:Longint):longint;
9:     begin
10:       if a>b then exit(a) else exit(b);
11:     end;
12:   Procedure zip(up,down:longint);
13:     var i,j:longint;
14:     begin
15:       fillchar(aa,sizeof(aa),0);
16:       fillchar(b,sizeof(b),0);
17:       for i:=1 to m do
18:         begin
19:           bb[i]:=bb[i-1];
20:           for j:=up to down do
21:             begin
22:               inc(aa[i],a[j,i]);
23:               if Magic[j,i] then begin inc(b[i]);inc(bb[i]);end;
24:             end;
25:         end;
26:     end;
27:   begin
28:     readln(n,m);
29:     for i:=1 to n do
30:       for j:=1 to m do
31:         read(a[i,j]);
32:     readln(t);fillchar(Magic,sizeof(Magic),false);
33:     for i:=1 to t do begin readln(x,y);Magic[x,y]:=true;end;
34:     ans:=-5120000000;
35:     for up:=1 to n do
36:       for down:=1 to n do
37:         begin
38:           Zip(up,down);
39:           fillchar(F,sizeof(F),0);
40:           for i:=1 to m do
41:             for j:=b[i] to bb[i] do
42:               begin
43:                 F[i,j]:=max(((F[i-1,j-b[i]] div (1<<(j-b[i])))+aa[i])*(1<
44:                              aa[i]*(1<
45:                 if F[i,j]>ans then ans:=F[i,j];
46:               end;
47:         end;
48:      writeln(ans);
49:    end.

转载于:https://www.cnblogs.com/Loongint/archive/2011/09/28/2194834.html

你可能感兴趣的文章
软件开发工作模型
查看>>
Java基础之字符串匹配大全
查看>>
面向对象
查看>>
lintcode83- Single Number II- midium
查看>>
移动端 响应式、自适应、适配 实现方法分析(和其他基础知识拓展)
查看>>
selenium-窗口切换
查看>>
使用vue的v-model自定义 checkbox组件
查看>>
[工具] Sublime Text 使用指南
查看>>
Hangfire在ASP.NET CORE中的简单实现方法
查看>>
Algorithm——何为算法?
查看>>
Web服务器的原理
查看>>
小强升职计读书笔记
查看>>
常用的107条Javascript
查看>>
#10015 灯泡(无向图连通性+二分)
查看>>
忘记root密码,怎么办
查看>>
linux设备驱动归纳总结(三):1.字符型设备之设备申请【转】
查看>>
《黑客与画家》 读书笔记
查看>>
bzoj4407: 于神之怒加强版
查看>>
mysql统计一张表中条目个数的方法
查看>>
ArcGIS多面体(multipatch)解析——引
查看>>