题意:在每行上选一个点,每个点都要各自对应的代价,同时相邻两行的点要满足 |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+线段树)的更多相关文章

  1. 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 ...

  2. 题解 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 ...

  3. ZOJ 3349 Special Subsequence 简单DP + 线段树

    同 HDU 2836 只不过改成了求最长子串. DP+线段树单点修改+区间查最值. #include <cstdio> #include <cstring> #include ...

  4. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  5. cf834D(dp+线段树区间最值,区间更新)

    题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...

  6. Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树)

    Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树) 题目链接 题意 给定一个nm的矩阵,每行取2k的矩阵,求总 ...

  7. 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 ...

  8. POJ1769 Minimizing maximizer(DP + 线段树)

    题目大概就是要,给一个由若干区间[Si,Ti]组成的序列,求最小长度的子序列,使这个子序列覆盖1到n这n个点. dp[i]表示从第0个到第i个区间且使用第i个区间,覆盖1到Ti所需的最少长度 对于Si ...

  9. [USACO2005][POJ3171]Cleaning Shifts(DP+线段树优化)

    题目:http://poj.org/problem?id=3171 题意:给你n个区间[a,b],每个区间都有一个费用c,要你用最小的费用覆盖区间[M,E] 分析:经典的区间覆盖问题,百度可以搜到这个 ...

随机推荐

  1. Django实现支付宝付款和微信支付

    支付宝支付和微信支付是当今互联网产品常用的功能,我使用Django Rest Framework实现了网页上支付宝支付和微信支付的一个通用服务,提供rpc接口给其他服务,包括获取支付宝支付页面url的 ...

  2. new 约束

    [new 约束] new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数.如果要使用 new 约束,则该类型不能为抽象类型. 当泛型类创建类型的新实例,请将 new 约束应用于类型参数 ...

  3. SaltStack 的插件特性

    :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; m ...

  4. 字符串匹配——C++使用Regex

    需要#include  < regex >   匹配 regex_match ("subject", std::regex("(sub)(.*)") ...

  5. Opencv Match Template(轮廓匹配)

    #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...

  6. spring+springmvc+mybatis+redis实现缓存

    先搭建好redis环境 需要的jar如下: jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:330 ...

  7. Python学习笔记_读Excel去重

    读取一个Excel文件,按照某列关键字,如果有重复则去掉 这里不介绍所有的解决办法,只是列出一个办法. 软件环境: OS:Win10 64位 Python 3.7 测试路径:D:\Work\Pytho ...

  8. Yii2在Form中处理短信验证码的Validator,耦合度最低的短信验证码验证方式

    短信验证码在目前大多数web应用中都会有,本文介绍一个基于Yii2 Validator方式的验证码验证方式. 在其他文章中看到的方式大多比较难做到一次封装,多次重用. 使用此方式的好处自然不用多说,V ...

  9. 从jvm运行机制来分析 String对象负值

    测试1: 代码 public class Test { public static void main(String[] args) { String s1="aaa"; f(s1 ...

  10. Spring框架总结(七)

    Spring代理模式:名词解释: 代理是一种开发的设计模式,用途:提供了对目标对象另外的访问方式,及通过对代理访问目标对象. 优势: 可以在目标对象实现的基础上,增强额外的功能操作,(扩展目标对象的功 ...