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/Others) Memory Limit: 62768/32768 K (Java/Others)
Total Submission(s): 821 Accepted Submission(s): 285
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?
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.
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
10
题意:就是每行选一个,上下两行需满足|j-k|≤f(i,j)+f(i+1,k).,问最小的cell和值。
分析:明显的dp,dp[i][j]表示到第i行选第j个的值,可是这样转移复杂度须要n*m*m,肯定会超时。
我们注意到|j-k|<=f(i,j)+f(i-1,k),那么对于i-1行的第k个我们更新[k-f(i-1,k),k+f(i-1,k)],对于第i行查询[j-f(i,j),j+f(i,j)],这样刚好满足的是要求的条件。
所以就用线段树维护一下查询区间最小值更新区间值就好。这样复杂度就是n*m*log(m)。。
/**
* @author neko01
*/
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <set>
#include <map>
using namespace std;
typedef long long LL;
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
#define pb push_back
#define mp(a,b) make_pair(a,b)
#define clr(a) memset(a,0,sizeof a)
#define clr1(a) memset(a,-1,sizeof a)
#define dbg(a) printf("%d\n",a)
typedef pair<int,int> pp;
const double eps=1e-8;
const double pi=acos(-1.0);
const int INF=0x7fffffff;
const LL inf=(((LL)1)<<61)+5;
const int N=105;
const int M=5005;
int a[N][M];
int f[N][M];
int dp[N][M];
struct node{
int l,r;
int Min;
int col;
}tree[M*4];
void build(int x,int l,int r)
{
tree[x].l=l,tree[x].r=r;
tree[x].Min=INF;
tree[x].col=INF;
if(l==r) return;
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
}
inline void push_down(int x)
{
if(tree[x].col!=INF)
{
tree[x<<1].col=min(tree[x].col,tree[x<<1].col);
tree[x<<1|1].col=min(tree[x<<1|1].col,tree[x].col);
tree[x<<1].Min=min(tree[x].col,tree[x<<1].Min);
tree[x<<1|1].Min=min(tree[x].col,tree[x<<1|1].Min);
tree[x].col=INF;
}
}
void update(int x,int l,int r,int val)
{
if(tree[x].l==l&&tree[x].r==r)
{
tree[x].Min=min(tree[x].Min,val);
tree[x].col=min(tree[x].col,val);
return;
}
push_down(x);
int mid=(tree[x].l+tree[x].r)>>1;
if(r<=mid) update(x<<1,l,r,val);
else if(l>mid) update(x<<1|1,l,r,val);
else
{
update(x<<1,l,mid,val);
update(x<<1|1,mid+1,r,val);
}
tree[x].Min=min(tree[x<<1].Min,tree[x<<1|1].Min);
}
int query(int x,int l,int r)
{
if(tree[x].l==l&&tree[x].r==r)
return tree[x].Min;
push_down(x);
int mid=(tree[x].l+tree[x].r)>>1;
if(r<=mid) return query(x<<1,l,r);
else if(l>mid) return query(x<<1|1,l,r);
else return min(query(x<<1,l,mid),query(x<<1|1,mid+1,r));
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
if(i==1) dp[1][j]=a[i][j];
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&f[i][j]);
for(int i=2;i<=n;i++)
{
build(1,1,m);
for(int j=1;j<=m;j++)
{
int l=max(1,j-f[i-1][j]);
int r=min(m,j+f[i-1][j]);
update(1,l,r,dp[i-1][j]);
}
for(int j=1;j<=m;j++)
{
int l=max(1,j-f[i][j]);
int r=min(m,j+f[i][j]);
dp[i][j]=query(1,l,r)+a[i][j];
}
}
int ans=INF;
for(int i=1;i<=m;i++)
ans=min(ans,dp[n][i]);
printf("%d\n",ans);
}
return 0;
}
hdu3698 Let the light guide us dp+线段树优化的更多相关文章
- 题解 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 ...
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
- HDU4719-Oh My Holy FFF(DP线段树优化)
Oh My Holy FFF Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) T ...
- UVA-1322 Minimizing Maximizer (DP+线段树优化)
题目大意:给一个长度为n的区间,m条线段序列,找出这个序列的一个最短子序列,使得区间完全被覆盖. 题目分析:这道题不难想,定义状态dp(i)表示用前 i 条线段覆盖区间1~第 i 线段的右端点需要的最 ...
- zoj 3349 dp + 线段树优化
题目:给出一个序列,找出一个最长的子序列,相邻的两个数的差在d以内. /* 线段树优化dp dp[i]表示前i个数的最长为多少,则dp[i]=max(dp[j]+1) abs(a[i]-a[j])&l ...
- 完美字符子串 单调队列预处理+DP线段树优化
题意:有一个长度为n的字符串,每一位只会是p或j.你需要取出一个子串S(注意不是子序列),使得该子串不管是从左往右还是从右往左取,都保证每时每刻已取出的p的个数不小于j的个数.如果你的子串是最长的,那 ...
- 【uva1502/hdu4117-GRE Words】DP+线段树优化+AC自动机
这题我的代码在hdu上AC,在uva上WA. 题意:按顺序输入n个串以及它的权值di,要求在其中选取一些串,前一个必须是后一个的子串.问d值的和最大是多少. (1≤n≤2×10^4 ,串的总长度< ...
- Contest20140906 ProblemA dp+线段树优化
Problem A 内存限制 256MB 时间限制 5S 程序文件名 A.pas/A.c/A.cpp 输入文件 A.in 输出文件 A.out 你有一片荒地,为了方便讨论,我们将这片荒地看成一条直线, ...
- POJ 3171.Cleaning Shifts-区间覆盖最小花费-dp+线段树优化(单点更新、区间查询最值)
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4721 Accepted: 1593 D ...
随机推荐
- 从数据表中随机抽取n条数据有哪几种方法(join实现可以先查数据然后再拼接)
从数据表中随机抽取n条数据有哪几种方法(join实现可以先查数据然后再拼接) 一.总结 一句话总结:最好的是这个:"SELECT * FROM table WHERE id >= (( ...
- iOS_06_Mac os X
Mac os X 系统简介 * 苹果公司专门为苹果电脑设计的操作系统. * 以坚如磐石的UNIX为基础,既简单易用且功能强大. * x 是一个罗马数字正式的发音位“十”(ten),连续了先前的Mac ...
- Flask项目之手机端租房网站的实战开发(二)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- 仿oschina 主界面的实现(二) -------Toolbar + DrawerLayout
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- 使用docker 搭建基础的 mysql 应用
mysql server是眼下比較流行的开源数据库server.以下介绍怎样使用docker来做一个mysql数据库服务 从站点直接 pull 一个 mysql 的镜像 core@localhost ...
- HDU - 4552 怪盗基德的挑战书 (后缀数组)
Description "在树最漂亮的那天,当时间老人再次把大钟平均分开时,我会降临在灯火之城的金字塔前.带走那最珍贵的笑容."这是怪盗基德盗取巴黎卢浮宫的<蒙娜丽莎的微笑& ...
- maven 解决Cannot change version of project facet Dynamic web module to 2.5
我们用Eclipse创建Maven结构的web项目的时候选择了Artifact Id为maven-artchetype-webapp,由于这个catalog比较老,用的servlet还是2.3的,而一 ...
- IIS FTP匿名登录不成功
FTP网站没有开启匿名登录的权限,对你没有看错.可能你的虚拟目录已经设置了如下所示的内容: 但是,单击上右图时,在其功能视图中的FTP身份验证中,可能并未启用"匿名身份验证",如下右图所示.启动 ...
- POJ 1833 生成排列
题目链接:POJ 1833 /************************************ * author : Grant Yuan * time : 2014/10/19 16:38 ...
- WPF遍历当前容器中某种控件的方法
原文:WPF遍历当前容器中某种控件的方法 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37591671/article/details/79 ...