题意:在每行上选一个点,每个点都要各自对应的代价,同时相邻两行的点要满足 |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. cdoj31-饭卡(card) (01背包)

    http://acm.uestc.edu.cn/#/problem/show/31 饭卡(card) Time Limit: 3000/1000MS (Java/Others)     Memory ...

  2. Gym101128F:Landscaping

    题意 有一片h*w的草坪,要把每一行从左到右修剪一遍,每一列从上到下修剪一遍.每个草坪要么是高低要么是平地.割草机从高地到平地或者从平地到高地,需要花费a.也可以把平地变为高地或者把高地变为平地,花费 ...

  3. 15-Call to your teacher(有向图的连通判断)

    链接:https://www.nowcoder.net/acm/contest/76/F来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...

  4. 文件操作putc

    putc是把一个字符写入到指定文件中,每写一个字符,文件指针自动加1. 我写了一个随机生成255字符到d:/456.txt的程序. int main() { FILE *p; int num[255] ...

  5. java的web配置文件的“<load-on-startup>的说明[转]

    <servlet> <servlet-name>log4jInitServlet</servlet-name> <servlet-class>org.s ...

  6. JS和DOM的关系

    DOM对象 DOM实际上是以面向对象方式描述的文档模型.DOM定义了表示和修改文档所需的对象.这些对象的行为和属性以及这些对象之间的关系. 根据W3C DOM规范,DOM是HTML与XML的应用编程接 ...

  7. 遍历properties文件

    Properties pro = new Properties();try {    InputStream inStr = ClassLoader.getSystemResourceAsStream ...

  8. HUST软件测试1506班: 第0周作业成绩

    说明 本次公布的成绩包含三次作业的结果: 毕博平台课前测试题 第0周作业1:开设博客 第0周作业2:博客阅读和思考 如果同学对作业结果存在异议,可以: 在线平台的第一周在线答疑中创建话题申诉. 或直接 ...

  9. 访问SAP的RFC

    .NET 环境Xp(sp3) vs2010, win2003 EN 32bit(sp2)winform,webform 引用sapnco.dll,sapnco_utils.dll(自动引用)配置文件需 ...

  10. RF和GBDT的区别

    Random Forest ​采用bagging思想,即利用bootstrap抽样,得到若干个数据集,每个数据集都训练一颗树. 构建决策树时,每次分类节点时,并不是考虑全部特征,而是从特征候选集中选取 ...