题解 HDU 3698 Let the light guide us Dp + 线段树优化
http://acm.hdu.edu.cn/showproblem.php?pid=3698
Let the light guide us
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 62768/32768 K (Java/Others)
Total Submission(s): 759 Accepted Submission(s): 253
Problem Description
Plain of despair was once an ancient battlefield where those brave spirits had rested in peace for thousands of years. Actually no one dare step into this sacred land until the rumor that “there is a huge gold mine underneath the plain” started to spread.
Recently an accident destroyed the eternal tranquility. Some greedy fools tried using powerful bombs to find the hidden treasure. Of course they failed and such behavior enraged those spirits--the consequence is that all the human villages nearby are haunted by ghosts.
In order to stop those ghosts as soon as possible, Panda the Archmage and Facer the great architect figure out a nice plan. Since the plain can be represented as grids of N rows and M columns, the plan is that we choose ONLY ONE cell in EACH ROW to build a magic tower so that each tower can use holy light to protect the entire ROW, and finally the whole plain can be covered and all spirits can rest in peace again. It will cost different time to build up a magic tower in different cells. The target is to minimize the total time of building all N towers, one in each row.
“Ah, we might have some difficulties.” said Panda, “In order to control the towers correctly, we must guarantee that every two towers in two consecutive rows share a common magic area.”
“What?”
“Specifically, if we build a tower in cell (i,j) and another tower in cell (i+1,k), then we shall have |j-k|≤f(i,j)+f(i+1,k). Here, f(i,j) means the scale of magic flow in cell (i,j).”
“How?”
“Ur, I forgot that you cannot sense the magic power. Here is a map which shows the scale of magic flows in each cell. And remember that the constraint holds for every two consecutive rows.”
“Understood.”
“Excellent! Let’s get started!”
Would you mind helping them?
Input
There are multiple test cases.
Each test case starts with a line containing 2 integers N and M (2<=N<=100,1<=M<=5000), representing that the plain consists N rows and M columns.
The following N lines contain M integers each, forming a matrix T of N×M. The j-th element in row i (Tij) represents the time cost of building a magic tower in cell (i, j). (0<=Tij<=100000)
The following N lines contain M integers each, forming a matrix F of N×M. The j-th element in row i (Fij) represents the scale of magic flows in cell (i, j). (0<=Fij<=100000)
For each test case, there is always a solution satisfying the constraints.
The input ends with a test case of N=0 and M=0.
Output
For each test case, output a line with a single integer, which is the minimum time cost to finish all magic towers.
Sample Input
3 5
9 5 3 8 7
8 2 6 8 9
1 9 7 8 6
0 1 0 1 2
1 0 2 1 1
0 2 1 0 2
0 0
Sample Output
10
Source
2010 Asia Fuzhou Regional Contest
分析:
这题显然是Dp .....dp[i][j] = min{dp[i + 1][k] + T[i][j]} |j-k|≤f(i,j)+f(i+1,k)
可是,一看数据规模,time有点捉急额、、、
斜率优化? .....没看出来。
四边形不等式? .....还是算了吧。
看来要优化状态转移方程“有点”困难......
让我们换个思路,能不能快速取到合适的k…
|j-k|≤f(i,j)+f(i+1,k)
Dp[i][j]的最优值,一定在以j为圆心,f[i][j]为半径的区间内
而dp[i-1][j]能更新以j为圆心,f[i-1][j] 为半径的区间。
这样,我们用每个dp[i-1][j] 更新每个[j – f[i - 1][j] , j + f[i - 1][j]]范围内的值。
计算 Dp[i][j]时,只需查询[j – f[i][j] , j + f[i][j]]范围内的最小值,既RMQ
So。。。。看代码吧。。。。
AC Code: 呵呵,在HDU上排名第13.......

#include <cstdio>
using namespace std;
const int maxn = 105;
const int maxm = 5005;
const int inf = 1 << 30;
inline int L(int rt) {return rt << 1;}
inline int R(int rt) {return rt << 1 | 1;}
inline int min(int a,int b) {return a < b ? a : b;}
struct Node
{
int l,r;
int min; // 区间最小值
int val;
} nd[maxm << 2];
int f[maxn][maxm];
int time[maxn][maxm];
int dp[maxn][maxm];
inline void pushDown(int rt)
{
if(nd[rt].val != inf) // val 有修改
{
nd[L(rt)].val = min(nd[L(rt)].val,nd[rt].val);
nd[R(rt)].val = min(nd[R(rt)].val,nd[rt].val);
nd[L(rt)].min = min(nd[L(rt)].min,nd[L(rt)].val);
nd[R(rt)].min = min(nd[R(rt)].min,nd[R(rt)].val);
nd[rt].val = inf;
}
}
void build(int l,int r,int rt) // 建线段树
{
nd[rt].l = l; nd[rt].r = r;
nd[rt].min = nd[rt].val = inf;
if(l == r) return;
int mid = (l + r) >> 1;
build(l,mid,L(rt));
build(mid + 1,r,R(rt));
}
void update(int l,int r,int val,int rt) // 更新区间[l,r]
{
if(l <= nd[rt].l && nd[rt].r <= r)
{
nd[rt].val = min(val,nd[rt].val);
nd[rt].min = min(nd[rt].val,nd[rt].min);
return;
}
int mid = (nd[rt].l + nd[rt].r) >> 1;
pushDown(rt);
if(l <= mid) update(l,r,val,L(rt));
if(r > mid) update(l,r,val,R(rt));
nd[rt].min = min(nd[L(rt)].min,nd[R(rt)].min);
}
int query(int l,int r,int rt) // RMQ
{
if(l <= nd[rt].l && nd[rt].r <= r)
return nd[rt].min;
int ret = inf;
int mid = (nd[rt].l + nd[rt].r) >> 1;
pushDown(rt);
if(l <= mid) ret = min(ret,query(l,r,L(rt)));
if(r > mid) ret = min(ret,query(l,r,R(rt)));
return ret;
}
inline void scan(int &n) // 读入加速
{
char c;
while(c = getchar(),c < '0' || c > '9');
n = c - '0';
while(c = getchar(),(c >= '0' && c <= '9')) n = n * 10 + c - '0';
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m) && (n != 0 || m != 0))
{
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
scan(time[i][j]);
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
scan(f[i][j]);
for(int i = 1;i <= m;i ++) // 初始化边界
dp[1][i] = time[1][i];
/////////////////////////////////////////////////////核心/////////////////////////////////////////////////////
for(int i = 2;i <= n;i ++)
{
build(1,m,1);
for(int j = 1;j <= m;j ++)
update(j - f[i - 1][j],j + f[i - 1][j],dp[i - 1][j],1);
for(int j = 1;j <= m;j ++)
dp[i][j] = query(j - f[i][j],j + f[i][j],1) + time[i][j];
}
/////////////////////////////////////////////////////END/////////////////////////////////////////////////////
int ans = inf;
for(int i = 1;i <= m;i ++)
ans = min(ans,dp[n][i]);
printf("%d\n",ans);
}
return 0;
}
题解 HDU 3698 Let the light guide us Dp + 线段树优化的更多相关文章
- hdu3698 Let the light guide us dp+线段树优化
http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java ...
- HDU 3698 Let the light guide us
Let the light guide us Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged on HDU. ...
- hdu 3698 Let the light guide us(线段树优化&简单DP)
Let the light guide us Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 62768/32768 K (Java/O ...
- HDU 3698 Let the light guide us(DP+线段树)(2010 Asia Fuzhou Regional Contest)
Description Plain of despair was once an ancient battlefield where those brave spirits had rested in ...
- HDU 4719 Oh My Holy FFF(DP+线段树)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)
Description N soldiers from the famous "*FFF* army" is standing in a line, from left to ri ...
- hdu 3698 UVA1490 Let the light guide us 线段树优化DP
题目链接 and 题目大意 hdu3698 但是 hdu的数据比较弱,所以在这luogu提交吧UVA1490 Let the light guide us 有一个\(n*m\)的平原,要求每行选一个点 ...
- hdu 5266 pog loves szh III(lca + 线段树)
I - pog loves szh III Time Limit:6000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- HDU 2795 Billboard(宣传栏贴公告,线段树应用)
HDU 2795 Billboard(宣传栏贴公告,线段树应用) ACM 题目地址:HDU 2795 Billboard 题意: 要在h*w宣传栏上贴公告,每条公告的高度都是为1的,并且每条公告都要 ...
随机推荐
- Python说文解字_半成品再加工
1. 其实在编写代码的时候,根据需求和程序员的喜好,对现有类中的属性和方法进行二次加工,原先所给与的属性和方法贴合自己想要的需求.这就是我们常说的“重写”和二次封装. 2. 比如我们对现有的库list ...
- MongoDB_走一波
Mongodb 一.mongodb的介绍 mongodb的优势 易扩展:NoSQL数据库种类繁多,但是一个共同的特定就是去掉关系数据库的关系型特性.数据之间无关系,这样非常容易扩展 大数据,高性能:N ...
- Istio流量治理原理之负载均衡
流量治理是一个非常宽泛的话题,例如: ● 动态修改服务间访问的负载均衡策略,比如根据某个请求特征做会话保持: ● 同一个服务有两个版本在线,将一部分流量切到某个版本上: ● 对服务进行保护,例如限制并 ...
- 3)在View中添加LBUTTONDOWN(标准消息)
1)消息一共分为四类: (1)标准消息-->以WM_ 开头的都是标准消息 (2)命令消息----> 菜单 工具条 快捷键(两个按键的组合是快捷键,一个按键是 WM_KEYDOWN( ...
- P3810 【模板】三维偏序(陌上花开)(CDQ分治)
题目背景 这是一道模板题 可以使用bitset,CDQ分治,K-DTree等方式解决. 题目描述 有 nn 个元素,第 ii 个元素有 a_iai.b_ibi.c_ici 三个属性,设 f(i) ...
- 十大经典排序算法(Javascript实现)
前言 总括: 本文结合动图详细讲述了十大经典排序算法用Javascript实现的过程. 原文博客地址:十大经典排序算法 公众号:「菜鸟学前端」,回复「666」,获取一揽子前端技术书籍 人生有情泪沾衣, ...
- Huffman编码实验
一. 实验目的 熟练掌握哈夫曼树的建立和哈夫曼编码的算法实现. 二. 实验内容 根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求赫夫曼编码,并能把给定的编码进行译码. 三. 实验要求 ...
- 0.3W微功率放大器
电路结构 电路摘自<晶体管电路设计(上)>. 电路采用+5V单电源供电,两级结构.Tr1构成共射极放大电路作为电压放大级:Tr3,Tr4构成推挽的射极跟随器作为输出级:Tr2作为射极跟随器 ...
- 菜鸟cmake使用
cmake是用过把源码生成visual studio 工程的工具,也就是生成.sln文件.他会把相应的库依赖都自动添加上. cmake有个CMakeLists.txt (具体语法这里先不介绍) 我都是 ...
- php先响应后处理
php响应异步请求或者返回时效要求高的接口中,可以先响应输出,再执行逻辑处理保存数据等任务 ob_end_clean(); ob_start(); echo '{"data":&q ...