给出N*M矩阵。每一个点建立灯塔有花费。每一个点的灯塔有连接范围,求每一行都建立一个灯塔的最小花费,要求每相邻两行的灯塔能够互相连接。满足 |j-k|≤f(i,j)+f(i+1,k)

DP思路,dp[i][j]=在第i行的j位置放置灯塔的最小花费。dp[i][j]=Min(dp[i-1][k]+a[i][j]),同一时候更新当前点能够覆盖该行的全部位置的最小值

要求上个区间的最小值,用线段树优化,否则超时

滚动数组,否则超内存

#include "stdio.h"
#include "string.h" int inf=0x3f3f3f3f; struct node
{
int Max,Min,lazy; // min记录区间最小值。max记录区间的最小值的最大值
short int l,r;
}data[2][20100]; int a[110][5010],b[110][5010]; int Min(int a,int b)
{
if (a<b) return a;
else return b;
} void Pushdown(int w,int k)
{
if (data[w][k].l==data[w][k].r) return ;
if (data[w][k].lazy==-1) return ; if (data[w][k].lazy<data[w][k*2].Min)
data[w][k*2].Min=data[w][k*2].lazy=data[w][k].lazy; if (data[w][k].lazy<data[w][k*2+1].Min)
data[w][k*2+1].Min=data[w][k*2+1].lazy=data[w][k].lazy; data[w][k].lazy=-1;
} void build(int w,int l,int r,int k)
{
int mid;
data[w][k].l=l;
data[w][k].r=r;
data[w][k].lazy=-1;
data[w][k].Min=inf;
data[w][k].Max=inf; if (l==r) return ; mid=(l+r)/2; build(w,l,mid,k*2);
build(w,mid+1,r,k*2+1);
} void updata(int w,int l,int r,int k,int op)
{
int mid; if (data[w][k].l==data[w][k].r)
{
if (data[w][k].Min>op) data[w][k].Max=data[w][k].Min=op;
return ;
}
if (data[w][k].l==l && data[w][k].r==r )
{
mid=(data[w][k].l+data[w][k].r)/2; if (op<data[w][k].Max) // 若以下区间存在最小值>op,则继续向下更新
{
updata(w,l,mid,k*2,op);
updata(w,mid+1,r,k*2+1,op);
data[w][k].Max=op;
}
if (op<data[w][k].Min)
data[w][k].Min=data[w][k].lazy=data[w][k].Max=op; return ;
} Pushdown(w,k); mid=(data[w][k].l+data[w][k].r)/2; if (r<=mid) updata(w,l,r,k*2,op);
else
if (l>mid) updata(w,l,r,k*2+1,op);
else
{
updata(w,l,mid,k*2,op);
updata(w,mid+1,r,k*2+1,op);
} data[w][k].Min=Min(data[w][k*2].Min,data[w][k*2+1].Min); } int query(int w,int l,int r,int k)
{
int mid;
if (data[w][k].l==l && data[w][k].r==r)
return data[w][k].Min; Pushdown(w,k); mid=(data[w][k].l+data[w][k].r)/2; if (r<=mid) return query(w,l,r,k*2);
else
if (l>mid) return query(w,l,r,k*2+1);
else
return Min(query(w,l,mid,k*2),query(w,mid+1,r,k*2+1));
} void pri(int w,int k)
{
if (data[w][k].l==data[w][k].r)
{
printf("%d ",data[w][k].Min);
return ;
}
Pushdown(w,k); pri(w,k*2);
pri(w,k*2+1);
}
int main()
{
int n,m,i,j,l,r,x;
while (scanf("%d%d",&n,&m)!=EOF)
{
if (n==0 && m==0) break;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
scanf("%d",&a[i][j]); for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
scanf("%d",&b[i][j]); build(1,1,m,1);
for (i=1;i<=m;i++)
{
l=i-b[1][i]; if (l<1) l=1;
r=i+b[1][i]; if (r>m) r=m;
updata(1,l,r,1,a[1][i]); // 初始化第一行每个位置的最优值
} for (i=2;i<=n;i++)
{
build(i%2,1,m,1);
for (j=1;j<=m;j++)
{
l=j-b[i][j]; if (l<1) l=1;
r=j+b[i][j]; if (r>m) r=m;
x=query(1-i%2,l,r,1); // 对于每一行的每个位置。查找上一行能够连接到该位置的最小值
updata(i%2,l,r,1,x+a[i][j]); // 更新该行该位置能够覆盖到的全部位置的最小值
}
} /* for (i=1;i<=n;i++)
{
printf("\n\n");
pri(i,1); }
printf("\n");*/ //debug printf("%d\n",data[n%2][1].Min); }
return 0;
}

HDU 3698 DP+线段树的更多相关文章

  1. hdu 3016 dp+线段树

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

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

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

  3. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  4. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  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 + 线段树优化

    http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java ...

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

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

随机推荐

  1. 20个Linux命令及Linux终端的趣事

    20个Linux命令及Linux终端的趣事 . 命令:sl (蒸汽机车) 你可能了解 ‘ls’ 命令,并经常使用它来查看文件夹的内容.但是,有些时候你可能会拼写成 ‘sl’ ,这时我们应该如何获得一些 ...

  2. linux之SQL语句简明教程---Alias

    接下来,我们讨论 alias (别名) 在 SQL 上的用处.最常用到的别名有两种: 栏位别名及表格别名. 简单地来说,栏位别名的目的是为了让 SQL 产生的结果易读.在之前的例子中,每当我们有营业额 ...

  3. HDOJ-1003 Max Sum(最大连续子段 动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=1003 给出一个包含n个数字的序列{a1,a2,..,ai,..,an},-1000<=ai<=100 ...

  4. Error: Linux下 mysql.sock文件丢失被删除解决方法

    在默认情况下,Mysql安装以后会在/tmp目录下生成一个mysql.sock文件,如该文件丢失则Mysql将不能够正常启动,解决方法:使用mysqld_safe 启动即可解决: #basedir:m ...

  5. 天气情况(思维,dp思想)

    天气情况 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  6. Dima and Salad(完全背包)

    Dima and Salad time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  7. 张冬:OpenPOWER CAPI为什么这么快?(二)

     张冬:OpenPOWER CAPI为什么这么快?(二) PMC公司数据中心存储架构师张冬 有了CAPI的FPGA是怎么做的? 首先认识一下这个体系里的三个角色: AFU(Acceleration ...

  8. js仿百度文库文档上传页面的分类选择器_第二版

    仿百度文库文档上传页面的多级联动分类选择器第二版,支持在一个页面同一时候使用多个分类选择器. 此版本号把HTML,CSS,以及图片都封装到"category.js"中.解决因文件路 ...

  9. SOA架构有基本的要求

    SOA在相对较粗的粒度上对应用服务或业务模块进行封装与重用: 服务间保持松散耦合,基于开放的标准, 服务的接口描述与具体实现无关: 灵活的架构 -服务的实现细节,服务的位置乃至服务请求的底层协议都应该 ...

  10. 利用maven中resources插件的copy-resources目标进行资源copy和过滤

    maven用可以利用如下配置进行资源过滤,pom.xml的配置如下: <build> <!-- 主资源目录 --> <resources> <resource ...