学习了一下凸优化DP,感觉挺有意思的

首先把所有点对称到左下角,然后以每个点为顶点画等腰直角三角形,将被覆盖的点去掉,现在所有点从左上到右下横纵坐标都是递增的,设坐标为$(x_{1\cdots M},y_{1\cdots M})$

设$f_{j,i}$表示拍$j$次照片覆盖$i$个点的最少覆盖方格数,枚举最后一个矩形覆盖到之前的哪个点,有$f_{j,i}=\min\limits_{0\leq k\lt i}f_{j-1,k}+\left(y_i-x_{k+1}+1\right)^2-\max\left(y_i-x_{i+1}+1,0\right)^2$,最后减去的是和下一个矩形的重复部分

直接斜率优化可以$O(nk)$,还需要再快一些

凸优化用于解决一类“恰好选$k$个”的问题,在这题中,如果把$f_{j,i}$关于$j$的图像画出来,可以看出它的斜率不减(这我不会证,官方题解上也没讲怎么证,但一般可以通过打差分表猜出结论)

对于常数$C$,设$g_i=\min\limits_jf_{j,i}+jC$,将$f$用转移展开后再回代$g$的定义,我们得到$g_i=\min\limits_{0\leq k\lt i}g_k+\left(y_i-x_{k+1}+1\right)^2-\max\left(y_i-x_{i+1}+1,0\right)^2+C$,可以$O(n)$求

$g_i$是将$\Delta f_{j,i}$平移后取$f$的最小值得到的,所以当$C$增大时使$g$取到最小值的$j$会变小,于是我们可以通过二分找到一个$p$使得当$C=p$时,使$g_M$取得最小值的$j_1\geq k$,当$C=p+1$时,使$g_M$取得最小值的$j_2\leq k$

我们已经得到了$f_{j_1,M},f_{j_2,M}$,现在要求$f_{k,M}\left(k\in[j_2,j_1]\right)$,因为再把$\Delta f_{j,i}$往上平移$1$单位就会让最小值位置偏移,所以$\Delta f_{j_2+1\cdots j_1,M}$全部相等,也就是说$f_{j_2\cdots j_1,M}$是一条直线,所以可以直接算出$f_{k,M}$

总的来说,如果$f_{j,i}$是关于$j$的凸函数,难以求值却易求最值,那么可以考虑偏移$\Delta f_{j,i}$来改变最小值的位置,进而求出某个位置的值

总时间复杂度$O(n\log m)$,相当优美

  1. #include<stdio.h>
  2. #include<vector>
  3. #include<math.h>
  4. using namespace std;
  5. typedef long long ll;
  6. typedef double du;
  7. typedef vector<int> vi;
  8. const du eps=1e-5;
  9. template<class t>void gmax(t&a,t b){
  10. if(a<b)a=b;
  11. }
  12. ll sqr(ll x){return x*x;}
  13. struct line{
  14. ll k,b;
  15. int i;
  16. line(ll k=0,ll b=0,int i=0):k(k),b(b),i(i){}
  17. ll v(ll x){return k*x+b;}
  18. }q[100010],u;
  19. du its(line a,line b){
  20. return(b.b-a.b)/(du)(a.k-b.k);
  21. }
  22. int x[100010],y[100010],M;
  23. ll g[100010];
  24. int b[100010];
  25. int get(ll c){
  26. int head,tail,i;
  27. head=tail=1;
  28. q[1]=line((x[1]-1)*-2,sqr(x[1]-1));
  29. for(i=1;i<=M;i++){
  30. while(head<tail&&its(q[head],q[head+1])<y[i]-eps)head++;
  31. if(head<tail&&fabs(its(q[head],q[head+1])-y[i])<eps){
  32. b[i]=min(q[head].i,q[head+1].i)+1;
  33. head++;
  34. }else
  35. b[i]=q[head].i+1;
  36. g[i]=q[head].v(y[i])+sqr(y[i])+c-sqr(max(y[i]-x[i+1]+1,0));
  37. if(i<M){
  38. u=line((x[i+1]-1)*-2,g[i]+sqr(x[i+1]-1),b[i]);
  39. while(head<tail&&its(q[tail],q[tail-1])>its(q[tail],u))tail--;
  40. q[++tail]=u;
  41. }
  42. }
  43. return b[M];
  44. }
  45. int a[1000010];
  46. ll inter(ll lc,ll rc,ll x){
  47. ll lx,ly,rx,ry;
  48. lx=get(lc);
  49. ly=g[M]-lc*lx;
  50. rx=get(rc);
  51. ry=g[M]-rc*rx;
  52. if(lx!=rx)
  53. return(ly-ry)/(rx-lx)*(rx-x)+ry;
  54. else
  55. return ly;
  56. }
  57. ll take_photos(int n,int m,int k,vi r,vi c){
  58. int i,t;
  59. ll l,_r,mid,ans;
  60. for(i=0;i<n;i++){
  61. r[i]++;
  62. c[i]++;
  63. if(r[i]<c[i])
  64. gmax(a[r[i]],c[i]);
  65. else
  66. gmax(a[c[i]],r[i]);
  67. }
  68. M=0;
  69. t=0;
  70. for(i=1;i<=m;i++){
  71. if(a[i]>t){
  72. M++;
  73. x[M]=i;
  74. y[M]=a[i];
  75. t=a[i];
  76. }
  77. }
  78. x[M+1]=m+1;
  79. k=min(k,M);
  80. #define r _r
  81. l=0;
  82. r=(ll)m*m;
  83. ans=0;
  84. while(l<=r){
  85. mid=(l+r)>>1;
  86. if(get(mid)>=k){
  87. ans=mid;
  88. l=mid+1;
  89. }else
  90. r=mid-1;
  91. }
  92. return inter(ans+1,ans,k);
  93. #undef r
  94. }

新的一年里要继续努力啊...

[UOJ240]aliens的更多相关文章

  1. Uva12206 Stammering Aliens 后缀数组&&Hash

    Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all effort ...

  2. HDU4080 Stammering Aliens(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...

  3. UVA 12206 - Stammering Aliens(后缀数组)

    UVA 12206 - Stammering Aliens 题目链接 题意:给定一个序列,求出出现次数大于m,长度最长的子串的最大下标 思路:后缀数组.搞出height数组后,利用二分去查找就可以 这 ...

  4. Stammering Aliens

    Stammering Aliens Time Limit: 2000MS   Memory Limit: 65536K       Description Dr. Ellie Arroway has ...

  5. XCOM2中敌对生物设计分析(Aliens篇)

    Aliens Aliens作为游戏设定中入侵的外星人,有各式外貌及奇特的战斗方式,掌握一些高能科技或利用精神力量进行攻击 Sectoid 使用灵能战斗的外星人,并无高级版本,初级便会使用精神控制,生命 ...

  6. UVA10570-Meeting with Aliens(枚举)

    Problem UVA1616-Caravan Robbers Accept: 531  Submit: 2490Time Limit: 3000 mSec Problem Description I ...

  7. UVA-10570 Meeting with Aliens (枚举+贪心)

    题目大意:将一个1~n的环形排列变成升序的,最少需要几次操作?每次操作可以交换任意两个数字. 题目分析:枚举出1的位置.贪心策略:每次操作都保证至少一个数字交换到正确位置上. # include< ...

  8. HDU4080Stammering Aliens(后缀数组+二分)

    However, all efforts to decode their messages have failed so far because, as luck would have it, the ...

  9. P5896 [IOI2016]aliens

    *IX. P5896 [IOI2016]aliens DP 优化方法大杂烩,详解 wqs 二分及其注意事项,斜率优化等其它 DP 优化方法. **** 团队赛 T6,没想到是 IOI 原题.当时看出来 ...

随机推荐

  1. UBIFS文件系统简介 与 利用mkfs.ubifs和ubinize两个工具制作UBI镜像 (完整理解版本)

    UBI文件系统简介 在linux-2.6.27以前,谈到Flash文件系统,大家很多时候多会想到cramfs.jffs2.yaffs2等文件系统. 它们也都是基于文件系 统+mtd+flash设备的架 ...

  2. linux查看目录的四种方法(ls只显示目录)【转】

    1.ls -d * amosli@amosli-pc:~$ ls -d * %APPDATA% develop many sorted.txt workspace bank Documents Mus ...

  3. bash脚本里su命令执行

    俩种方法 1.可以使用 <<EOF 参数实现. 脚本内容:cat test.sh代码如下: #!/bin/bashsu - test <<EOFpwd;exit;EOF 2.当 ...

  4. Python Challenge 第 5 关攻略:peak

    # -*- coding: utf-8 -*- # @Time : 2018/9/26 14:03 # @Author : cxa # @File : pickledemo.py # @Softwar ...

  5. ASP.NET MVC 防止跨站请求伪造(CSRF)攻击的方法

    在HTTP POST请求中,我们多次在View和Controller中看下如下代码: View中调用了Html.AntiForgeryToken(). Controller中的方法添加了[Valida ...

  6. [转载]如何在C++03中模拟C++11的右值引用std::move特性

    本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalu ...

  7. Flask:初次使用Blueprints

    Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2,Eclipse Oxygen.1a Release (4.7.1a),PyDev 6.3.2 本文为记录自己第一次使用 ...

  8. 【Android开发日记】之入门篇(八)——Android数据存储(下)

    废话不多说了,紧接着来讲数据库的操作吧.Come On! 提到数据存储问题,数据库是不得不提的.数据库是用来存储关系型数据的不二利器.Android为开发者提供了强大的数据库支持,可以用来轻松地构造基 ...

  9. 监听 手机back键和顶部的回退

    // 回退事件,监听 手机back键和顶部的回退 pushHistory(); window.addEventListener("popstate", function(e) { ...

  10. java基础65 JavaScript中的Window对象(网页知识)

    1.javaScript组成部分 1.EMCAScript(基本语法)    2.BOM(Browser Object Model):浏览器对象模型            浏览器对象模型中的浏览器的各 ...