大意: $n*m$棋盘, 初始位置$(1,1)$, 横坐标为$\frac{m+1}{2}$时可以向下走, 否则只能左右走, 每走一步花费$1$秒. 有$k$管奶, 第$i$罐位置$(r_i,c_i)$, 要花费$t_i$的时间去喝. 对于所有的$1\le i\le k$, 求出喝完$i$管奶最短用时.

实现略复杂的$dp$题, 直接按照官方题解写了.

主要思路是对每一行求出向左/向右喝$x$罐奶的最少用时, 然后$dp$合并答案.

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstdio>
  4. #include <queue>
  5. #define REP(i,a,n) for(int i=a;i<=n;++i)
  6. #define PER(i,a,n) for(int i=n;i>=a;--i)
  7. #define x first
  8. #define y second
  9. #define pb push_back
  10. using namespace std;
  11. typedef long long ll;
  12. typedef pair<int,int> pii;
  13. const ll INF = 1e15;
  14. const int N = 1e4+10;
  15. int n, m, k, b[N];
  16. struct {int x,y,t;} a[N];
  17. ll ans[N];
  18. vector<pii> v[N];
  19. vector<ll> solve(vector<pii> a, int s, int x) {
  20. a.insert(a.begin(),pii(s,0));
  21. vector<ll> ret(a.size(),INF), t(ret);
  22. ret[0] = x==-1?0:abs(x-s);
  23. t[0] = 0;
  24. for (int i=1; i<a.size(); ++i) {
  25. int len = abs(a[i].x-a[i-1].x);
  26. REP(j,0,i-1) t[j]+=len;
  27. PER(j,1,i) t[j]=min(t[j],t[j-1]+a[i].y);
  28. REP(j,1,i) ret[j]=min(ret[j],t[j]+(x==-1?0:abs(x-a[i].x)));
  29. }
  30. return ret;
  31. }
  32. vector<ll> Merge(const vector<ll> &L, const vector<ll> &R) {
  33. vector<ll> ret(L.size()+R.size()-1,INF);
  34. for (int i=0;i<L.size();++i) {
  35. for (int j=0;j<R.size();++j) {
  36. ret[i+j] = min(ret[i+j], L[i]+R[j]);
  37. }
  38. }
  39. return ret;
  40. }
  41.  
  42. void work() {
  43. scanf("%d%d%d", &n, &m, &k);
  44. *b = 0;
  45. REP(i,1,k) {
  46. scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].t);
  47. b[++*b] = a[i].x;
  48. }
  49. b[++*b] = 1;
  50. sort(b+1,b+1+*b),*b=unique(b+1,b+1+*b)-b-1;
  51. REP(i,1,*b) v[i].clear();
  52. REP(i,1,k) {
  53. a[i].x=lower_bound(b+1,b+1+*b,a[i].x)-b;
  54. v[a[i].x].pb(pii(a[i].y,a[i].t));
  55. ans[i] = INF;
  56. }
  57. REP(i,1,*b) sort(begin(v[i]),end(v[i]));
  58. auto g = solve(v[1],1,-1);
  59. for (int i=0;i<g.size();++i) {
  60. ans[i] = min(ans[i], g[i]);
  61. }
  62. int cur = 0;
  63. vector<ll> f[2];
  64. f[0] = solve(v[1],1,(m+1)/2);
  65. REP(i,2,*b) {
  66. cur ^= 1;
  67. auto p = lower_bound(begin(v[i]),end(v[i]),pii((m+1)/2,0));
  68. vector<pii> L(begin(v[i]),p), R(p,end(v[i]));
  69. reverse(begin(L),end(L));
  70. auto f0 = solve(L,(m+1)/2,(m+1)/2), f1 = solve(R,(m+1)/2,(m+1)/2);
  71. auto g0 = solve(L,(m+1)/2,-1), g1 = solve(R,(m+1)/2,-1);
  72. g0 = Merge(f1,g0), g1 = Merge(f0,g1);
  73. auto g = g0;
  74. for (int j=0;j<g.size();++j) {
  75. g[j] = min(g[j], g1[j]);
  76. }
  77. g = Merge(f[!cur],g);
  78. f[cur] = Merge(f[!cur],Merge(f0,f1));
  79. for (int j=0;j<g.size();++j) {
  80. ans[j] = min(ans[j], g[j]+b[i]-b[i-1]);
  81. f[cur][j] += b[i]-b[i-1];
  82. }
  83. }
  84. REP(i,1,k) {
  85. if (i==k) printf("%lld\n",ans[i]);
  86. else printf("%lld ",ans[i]);
  87. }
  88. }
  89.  
  90. int main() {
  91. int t;
  92. scanf("%d", &t);
  93. while (t--) work();
  94. }

2019杭电多校一 C. Milk (dp)的更多相关文章

  1. 2019杭电多校一 A. Blank (dp)

    大意: 长为$n$的数组, 每个位置范围$[0,3]$, $m$个限制$(l,r,x)$表示$[l,r]$内有$x$种数, 求方案数. 维护每个数字最后一次出现位置, 暴力$DP$ 实现时有个技巧是把 ...

  2. [2019杭电多校第八场][hdu6667]Roundgod and Milk Tea

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6667 题目大意是说n个班级,每个班级有ai人和bi杯茶,每个人只能喝其他班的茶并且只能喝一杯.问最多有 ...

  3. 2019杭电多校&CCPC网络赛&大一总结

    多校结束了, 网络赛结束了.发现自己还是太菜了,多校基本就是爆零和签到徘徊,第一次打这种高强度的比赛, 全英文,知识点又很广,充分暴露了自己菜的事实,发现数学还是很重要的.还是要多刷题,少玩游戏. 网 ...

  4. 2019杭电多校第一场hdu6581 Vacation

    Vacation 题目传送门 update(O(n)) 看了那个O(n)的方法,感觉自己想的那个O(nlogn)的好傻,awsl. 0车最终通过停车线的时候,状态一定是某个车堵住后面的所有车(这个车也 ...

  5. 2019杭电多校第二场hdu6601 Keen On Everything But Triangle

    Keen On Everything But Triangle 题目传送门 解题思路 利用主席树求区间第k小,先求区间内最大的值,再求第二大,第三大--直到找到连续的三个数可以构成一个三角形.因为对于 ...

  6. 2019杭电多校第二场hdu6602 Longest Subarray(线段树)

    Longest Subarray 题目传送门 解题思路 本题求一个最大的子区间,满足区间内的数字要么出现次数大于等于k次,要么没出现过.给定区间内的数字范围是1~c. 如果r为右边界,对于一种数字x, ...

  7. Rikka with Game[技巧]----2019 杭电多校第九场:1005

      Rikka with Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Othe ...

  8. 2019杭电多校 hdu6662 Acesrc and Travel (树形dp

    http://acm.hdu.edu.cn/showproblem.php?pid=6662 题意:有两个人在树上博弈,每个点节点有两个分数a[i]和b[i],先手先选择一个点,后手在先手选的点的相邻 ...

  9. 2019杭电多校 hdu6659 Acesrc and Good Numbers

    http://acm.hdu.edu.cn/showproblem.php?pid=6659 题意:给你d,x,让求满足f(d,n)=n的最大n(n<=x),其中f(d,n)表示数字d在从1到n ...

随机推荐

  1. php实现excel单元格合并,字体加粗居中等操作

    使用的是phpexcel,基本用的原生语法,所见即所得,直接复制下面代码,即可: // 引用phpexcel类 $this->load->library('PHPExcel'); // 创 ...

  2. 微信小程序之分享功能

    说到分享 大家都会想到手机右上角点击不就分享了么?对的没错,那样是分享转发的是小程序  而不是指定的某个页面,所以自己动手丰衣足食,自己写一个转发功能被, 其实也没那么可怕,主要参考的是微信小程序AP ...

  3. mac下PHP安装mongo扩展

    说明:mongo 和 mongodb是两个扩展,目前mongo扩展已经被废弃,建议使用mongodb扩展,但对于一些老项目还在使用mongo扩展的,请参考此文. mongodb和其他PHP扩展的安装方 ...

  4. 画布之ShapeDrawable

    package com.loaderman.customviewdemo; import android.content.Context; import android.graphics.Canvas ...

  5. Release报错Debug无错

    代码在Release模式下会crash,Debug模式下可以运行,最后定位到原因 for (size_t j = 0; j < ids.size()-1; ++j) { } 发现问题是Relea ...

  6. Jsoup-简单爬取知乎推荐页面(附:get_agent())

    总览 今天我们就来小用一下Jsoup,从一个整体的角度来看一看爬虫 一个基本的爬虫框架包括: [x] 解析网页 [x] 失败重试 [x] 抓取内容保存至本地 [x] 多线程抓取 *** 分模块讲解 将 ...

  7. 实现下拉弹出视图和Block的简单实现

    实现效果如下: 实现代码如下: @interface ViewController ()<UIViewControllerTransitioningDelegate> { UILabel ...

  8. Win10安装PostgreSQL9.6

    首先去 官网 下载PostgreSQL 9.6. 可以看到最新版已经到11了,但是我们这里还是以9.6.10版本为例进行下载. 下载好之后点击进行安装,安装期间的一些参数如下: 默认的安装位置是C:\ ...

  9. destoon 6.0 手机站支持在所有浏览器访问

    我们的在本地调试destoon 6.0的手机站模板时,用浏览器的自带审查元素很不方便. 可是destoon 默认是在电脑端打不开手机站,如果这个设置能够去除掉,那就可以了. 去掉这个限制,指需要两步 ...

  10. KMeans聚类

    常用的聚类方法: ①分裂方法: K-Means算法(K-平均).K-MEDOIDS算法(K-中心点).CLARANS算法(基于选择的算法) ②层次分析方法: BIRCH算法(平衡迭代规约和聚类).CU ...