题解 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的,并且每条公告都要 ...
随机推荐
- c# 异常处理 try --catch
初学 try---catch 语法 try { 可能会出现异常的代码; 异常出现的那行代码下面的代码全不会执行,直接跳到catch中执行 ... ... } //try和catch之间不能有其他的代码 ...
- 第04项目:淘淘商城(SpringMVC+Spring+Mybatis) 的学习实践总结【第一天】
本人做过一年的MATLAB编程和简单维护过VB和C++的项目.是跟着网上获得的黑马的Java双元视频课来自学入门Java知识和常用框架的使用. 淘淘商城(SpringMVC+Spring+Mybati ...
- delphixe7支持MYSQL连接的方式
由于工作需要,给出配套能用的版本,目前仅在win10 64位 XE7测试通过,如果换成其他环境,请根据自己的环境使用如下路径的dbxmys.dll 32位系统 E:\Program Files (x8 ...
- 实操windows2008搭建IIS php mysql
一.IIS的安装直接略过 二.主要记录PHP.MYSQL环境的搭建 1.本次环境搭建使用的环境版本号对应如下: 1.PHP:PHP 7.2 (7.2.28) 下载地址:https://windows. ...
- python函数中的参数(关键字参数,默认参数,位置参数,不定长参数)
默认参数:定义函数的时候给定变量一个默认值. def num(age=1): 位置参数:调用函数的时候根据定义函数时的形参位置和实参位置进行引用. 关键字参数:如果定义的函数中含有关键字参数,调用函数 ...
- python-day5爬虫基础之正则表达式2
dot: '.'匹配任意的字符 '*'匹配任意多个(0到多个) 如图所示, 程序运行结果是abc,之所以没有匹配\n,是因为\n是换行符,它就代表这个字符串是两行的,而正则表达式是一行一行去匹配的.在 ...
- 分享一套好看的PyCharm Color Shceme 配色方案
配色方案图1 点击可查看大图 (color shceme 配色文件下载链接已经放在文末) 配色方案图2 配色方案图3 picture1 picture2 整体效果 下载链接 https://files ...
- GCC与gcc,g++区别
看的Linux公社的一篇文章,觉得不错,内容复制过来了. 其实在这之前,我一直以为gcc和g++是一个东西,只是有两个不同的名字而已,今天在linux下编译一个c代码时出现了错误才找了一下gcc和g+ ...
- JavaScript之OOP
本文介绍下js中OOP的一些用法: 由上图可得: 1.typeof null结果是object,所以需要用与运算符再次判断是否为空. 2.构造器实现重载后,可依序传入参数或传入对象. 由上图可得:要实 ...
- iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码
iOS精选源码 如丝般顺滑的微信朋友圈(点赞,评论,图文混排表情,... 动态菜单第三版本:动态项,自适应方向 仿appstore首页滚动效果 iOS 透明导航栏方案 TransparentNavig ...