hdu3698 Let the light guide us(dp+线段树)
题意:在每行上选一个点,每个点都要各自对应的代价,同时相邻两行的点要满足 |j-k|≤f(i,j)+f(i+1,k)。问最小代价是多少。
题解:
不难发现这是一道dp,状态转移方程如下$dp[i][j]=min\{dp[i-1][k]\}+t[i][j](|j-k|≤f(i,j)+f(i+1,k))$
然而如果直接进行转移是要T飞的
所以如何快速求$k$呢?
可以发现,$dp[i-1][k]$只会对一个区间的答案产生影响,而$dp[i][j]$的答案必定是一个区间中的最小值加上自己的时间
于是就是区间修改和区间查询了,之间上线段树
ps:因为$dp$数组每一行都会更新,实际上可以省掉第一维的空间
//minamoto
#include<cstdio>
#include<iostream>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<],z[];int C=-,Z;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
if(C><<)Ot();if(x<)sr[++C]=,x=-x;
while(z[++Z]=x%+,x/=);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=,M=,inf=0x3f3f3f3f;
int t[N][M],f[N][M],dp[M],sum[M<<],add[M<<];
int n,m;
void pushdown(int p){
if(add[p]!=inf){
cmin(add[p<<],add[p]),cmin(add[p<<|],add[p]);
cmin(sum[p<<],add[p<<]),cmin(sum[p<<|],add[p<<|]);
add[p]=inf;
}
}
void build(int l,int r,int p){
sum[p]=add[p]=inf;
if(l==r) return;
int mid=l+r>>;
build(l,mid,p<<),build(mid+,r,p<<|);
}
void update(int ql,int qr,int x,int l,int r,int p){
if(ql<=l&&qr>=r){
cmin(add[p],x),cmin(sum[p],add[p]);return;
}
int mid=l+r>>;
pushdown(p);
if(ql<=mid) update(ql,qr,x,l,mid,p<<);
if(qr>mid) update(ql,qr,x,mid+,r,p<<|);
sum[p]=min(sum[p<<],sum[p<<|]);
}
int query(int ql,int qr,int l,int r,int p){
if(ql<=l&&qr>=r) return sum[p];
int mid=l+r>>;
pushdown(p);
int res=inf;
if(ql<=mid) cmin(res,query(ql,qr,l,mid,p<<));
if(qr>mid) cmin(res,query(ql,qr,mid+,r,p<<|));
return res;
}
int main(){
//freopen("testdata.in","r",stdin);
while(true){
n=read(),m=read();
if(n==&&m==) break;
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
t[i][j]=read();
for(int i=;i<=n;++i)
for(int j=;j<=m;++j)
f[i][j]=read();
for(int i=;i<=m;++i) dp[i]=t[][i];
for(int i=;i<=n;++i){
build(,m,);
for(int j=;j<=m;++j)
update(j-f[i-][j],j+f[i-][j],dp[j],,m,);
for(int j=;j<=m;++j)
dp[j]=query(j-f[i][j],j+f[i][j],,m,)+t[i][j];
}
int ans=inf;
for(int i=;i<=m;++i) cmin(ans,dp[i]);
print(ans);
}
Ot();
return ;
}
hdu3698 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 Dp + 线段树优化
http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java ...
- ZOJ 3349 Special Subsequence 简单DP + 线段树
同 HDU 2836 只不过改成了求最长子串. DP+线段树单点修改+区间查最值. #include <cstdio> #include <cstring> #include ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- cf834D(dp+线段树区间最值,区间更新)
题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...
- Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树)
Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树) 题目链接 题意 给定一个nm的矩阵,每行取2k的矩阵,求总 ...
- 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 ...
- POJ1769 Minimizing maximizer(DP + 线段树)
题目大概就是要,给一个由若干区间[Si,Ti]组成的序列,求最小长度的子序列,使这个子序列覆盖1到n这n个点. dp[i]表示从第0个到第i个区间且使用第i个区间,覆盖1到Ti所需的最少长度 对于Si ...
- [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)
题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...
随机推荐
- redis cluster test
cp /test/tests/redis.conf /etc redis-server /etc/redis.conf redis-trib.rb create --replicas 1 172.17 ...
- 【ZOJ 3228】Searching the String 【AC自动机】
题意 给出n个模式串和一个文本串,输出各个模式串在文本串中出现的次数.模式串有两种类型,0类型代表可以有重叠,1类型代表不能有重叠.模式串可能出现重复. 分析 算是AC自动机的模板题? 因为模式串可以 ...
- c# ftp 上传文件 与 下载文件
接着上一篇说. 上一篇说了根据配置文件获取路径,并判断路径在服务器中是否存在.如果不存在则在服务器中建立一个. 然后就是往路径下面传输文件了.. 代码: //连接ftp private void Co ...
- 用 Markdown 写作(一)——添加文章页内导航
Markdown 可以用更简化的标记来写文章,基本的语法可以参考Markdown 语法说明 (简体中文版). 我平时很少按照论文的写法去写博客,说来忏愧,因为很少写技术性的文章,最近看到百度百科和很多 ...
- (转)C#中的 Interfaces (For 初学者们)
http://blog.sina.com.cn/s/blog_574c993d0100d59n.html
- python中fork()函数生成子进程分析-乾颐堂
python的os module中有fork()函数用于生成子进程,生成的子进程是父进程的镜像,但是它们有各自的地址空间,子进程复制一份父进程内存给自己,两个进程之 间的执行是相互独立的,其执行顺序可 ...
- a Concise Sparse Matrix package
简明稀疏矩阵包 https://github.com/kulhanek/csparse https://github.com/kulhanek/csparse
- wireshark问题
上一篇wireshark编译成功了,生成了相应的wireshark.exe,dumpcap.exe等可执行文件(这些文件都是可以运行的),编译工具用的是VS2010,但是新生成的文件和文件夹中没有找到 ...
- [GO]匿名字段
package main import ( "fmt" ) type Person struct { name string sex byte age int } type Stu ...
- 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)
本篇文章主要介绍了"两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试)",主要涉及到两款JSON类库Jackson与JSON-lib的性能对比(新增第三款 ...