给出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]),同一时候更新当前点能够覆盖该行的全部位置的最小值

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

滚动数组,否则超内存

  1. #include "stdio.h"
  2. #include "string.h"
  3.  
  4. int inf=0x3f3f3f3f;
  5.  
  6. struct node
  7. {
  8. int Max,Min,lazy; // min记录区间最小值。max记录区间的最小值的最大值
  9. short int l,r;
  10. }data[2][20100];
  11.  
  12. int a[110][5010],b[110][5010];
  13.  
  14. int Min(int a,int b)
  15. {
  16. if (a<b) return a;
  17. else return b;
  18. }
  19.  
  20. void Pushdown(int w,int k)
  21. {
  22. if (data[w][k].l==data[w][k].r) return ;
  23. if (data[w][k].lazy==-1) return ;
  24.  
  25. if (data[w][k].lazy<data[w][k*2].Min)
  26. data[w][k*2].Min=data[w][k*2].lazy=data[w][k].lazy;
  27.  
  28. if (data[w][k].lazy<data[w][k*2+1].Min)
  29. data[w][k*2+1].Min=data[w][k*2+1].lazy=data[w][k].lazy;
  30.  
  31. data[w][k].lazy=-1;
  32. }
  33.  
  34. void build(int w,int l,int r,int k)
  35. {
  36. int mid;
  37. data[w][k].l=l;
  38. data[w][k].r=r;
  39. data[w][k].lazy=-1;
  40. data[w][k].Min=inf;
  41. data[w][k].Max=inf;
  42.  
  43. if (l==r) return ;
  44.  
  45. mid=(l+r)/2;
  46.  
  47. build(w,l,mid,k*2);
  48. build(w,mid+1,r,k*2+1);
  49. }
  50.  
  51. void updata(int w,int l,int r,int k,int op)
  52. {
  53. int mid;
  54.  
  55. if (data[w][k].l==data[w][k].r)
  56. {
  57. if (data[w][k].Min>op) data[w][k].Max=data[w][k].Min=op;
  58. return ;
  59. }
  60. if (data[w][k].l==l && data[w][k].r==r )
  61. {
  62. mid=(data[w][k].l+data[w][k].r)/2;
  63.  
  64. if (op<data[w][k].Max) // 若以下区间存在最小值>op,则继续向下更新
  65. {
  66. updata(w,l,mid,k*2,op);
  67. updata(w,mid+1,r,k*2+1,op);
  68. data[w][k].Max=op;
  69. }
  70. if (op<data[w][k].Min)
  71. data[w][k].Min=data[w][k].lazy=data[w][k].Max=op;
  72.  
  73. return ;
  74. }
  75.  
  76. Pushdown(w,k);
  77.  
  78. mid=(data[w][k].l+data[w][k].r)/2;
  79.  
  80. if (r<=mid) updata(w,l,r,k*2,op);
  81. else
  82. if (l>mid) updata(w,l,r,k*2+1,op);
  83. else
  84. {
  85. updata(w,l,mid,k*2,op);
  86. updata(w,mid+1,r,k*2+1,op);
  87. }
  88.  
  89. data[w][k].Min=Min(data[w][k*2].Min,data[w][k*2+1].Min);
  90.  
  91. }
  92.  
  93. int query(int w,int l,int r,int k)
  94. {
  95. int mid;
  96. if (data[w][k].l==l && data[w][k].r==r)
  97. return data[w][k].Min;
  98.  
  99. Pushdown(w,k);
  100.  
  101. mid=(data[w][k].l+data[w][k].r)/2;
  102.  
  103. if (r<=mid) return query(w,l,r,k*2);
  104. else
  105. if (l>mid) return query(w,l,r,k*2+1);
  106. else
  107. return Min(query(w,l,mid,k*2),query(w,mid+1,r,k*2+1));
  108. }
  109.  
  110. void pri(int w,int k)
  111. {
  112. if (data[w][k].l==data[w][k].r)
  113. {
  114. printf("%d ",data[w][k].Min);
  115. return ;
  116. }
  117. Pushdown(w,k);
  118.  
  119. pri(w,k*2);
  120. pri(w,k*2+1);
  121. }
  122. int main()
  123. {
  124. int n,m,i,j,l,r,x;
  125. while (scanf("%d%d",&n,&m)!=EOF)
  126. {
  127. if (n==0 && m==0) break;
  128. for (i=1;i<=n;i++)
  129. for (j=1;j<=m;j++)
  130. scanf("%d",&a[i][j]);
  131.  
  132. for (i=1;i<=n;i++)
  133. for (j=1;j<=m;j++)
  134. scanf("%d",&b[i][j]);
  135.  
  136. build(1,1,m,1);
  137. for (i=1;i<=m;i++)
  138. {
  139. l=i-b[1][i]; if (l<1) l=1;
  140. r=i+b[1][i]; if (r>m) r=m;
  141. updata(1,l,r,1,a[1][i]); // 初始化第一行每个位置的最优值
  142. }
  143.  
  144. for (i=2;i<=n;i++)
  145. {
  146. build(i%2,1,m,1);
  147. for (j=1;j<=m;j++)
  148. {
  149. l=j-b[i][j]; if (l<1) l=1;
  150. r=j+b[i][j]; if (r>m) r=m;
  151. x=query(1-i%2,l,r,1); // 对于每一行的每个位置。查找上一行能够连接到该位置的最小值
  152. updata(i%2,l,r,1,x+a[i][j]); // 更新该行该位置能够覆盖到的全部位置的最小值
  153. }
  154. }
  155.  
  156. /* for (i=1;i<=n;i++)
  157. {
  158. printf("\n\n");
  159. pri(i,1);
  160.  
  161. }
  162. printf("\n");*/ //debug
  163.  
  164. printf("%d\n",data[n%2][1].Min);
  165.  
  166. }
  167. return 0;
  168. }

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. css案例学习之relative与absolute

    代码 <!DOCTYPE html PUBliC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.o ...

  2. linux的7种运行级别<学习笔记>

    Linux系统有7个运行级别(runlevel) 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆 运行级别 ...

  3. Linux磁盘及文件系统管理 3---- 文件系统

    1 文件系统 1 操作系统通过文件系统来管理文件及数据,磁盘或分区需要创建文件系统之后才能为操作系统使用,创建文件系统的过程称为格式化 2 没有文件系统的设备称为裸设备 3 常见的文件系统有fat32 ...

  4. linux C之access函数 (20

    http://blog.sina.com.cn/s/blog_6a1837e90100uh5d.html linux C之access函数 (20access():判断是否具有存取文件的权限 相关函数 ...

  5. MapReduce工作机制

    MapReduce是什么? MapReduce是一种分布式计算模型,由Google提出,主要用于搜索领域,MapReduce程序本质上是并行运行的,因此可以解决海量数据的计算问题. MapReduce ...

  6. Linux启动新进程的几种方法及比较

    有时候,我们需要在自己的程序(进程)中启动另一个程序(进程)来帮助我们完成一些工作,那么我们需要怎么才能在自己的进程中启动其他的进程呢?在Linux中提供了不少的方法来实现这一点,下面就来介绍一个这些 ...

  7. 多进程用户并发处理Demo(C#版)

    这个示例主要演示的是在多进程操作数据库时,如何避免并发重复数据入库的例子. 过多的线程理论不再阐述,网上.书上皆有. 项目采用 Asp.Net Framework 4.5 / Mysql 5.4 数据 ...

  8. oracle em命令行配置及界面按钮乱码问题解决方法

    一.配置EM dbconsole db [oracle@rusky ~]$ lsnrctl start [oracle@rusky ~]$ emctl start dbconsoleTZ set to ...

  9. 【泛化物品】【HDU1712】【ACboy needs your help】

    ACboy needs your help Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  10. SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用

    近段时间以来,一直在探究SQL Server查询性能的问题,当然也漫无目的的查找了很多资料,也从网上的大神们的文章中学到了很多,在这里,向各位大神致敬.正是受大神们无私奉献精神的影响,所以小弟也作为回 ...