题意描述

Lazy Cows

给定一个 \(2\times b\) 的矩形,和 \(n\) 个矩形上的点。

要求你用 \(k\) 个矩形覆盖这 \(n\) 个点,使得每个点都被覆盖的前提下这些矩形的面积和最小。

算法分析

这道题的阶段性很强(按照目标点的纵坐标),但是状态不太好表示,于是想到状压。

首先将图改变一下,便于 DP:

  1. 将输入的奶牛按照位置从小到大排序。
  2. 在每个不同的位置(横坐标)记录一次。
  3. 如果这个位置(横坐标)的仅上面有奶牛,标记为 \(1\);仅下面有奶牛,标记为 \(2\);上下都有,标记为 \(3\)。

那么显然,改变之后的图中不同牛的数量 \(\leq n\)。

设计状态

设 \(f(i,j,0\)~\(4)\) 表示:到第 \(i\) 个牛的位置,用了 \(j\) 个牛舍,状态为 \(0\)~\(4\) 的最小面积。

解释一下状态:

  1. 表示上下都没有牛舍,这种情况仅存在于初始化。
  2. 表示上面有牛舍,下面没有。
  3. 表示上面没有牛舍,下面有。
  4. 表示上下都有牛舍,而且是同一个牛舍。
  5. 表示上下都有牛舍,而且是不同牛舍。

预处理

就是...,酱紫:

\(f(0,0,0)=0\)

\(f(1,1,1)=f(1,1,2)=1\)

\(f(1,1,3)=f(1,2,4)=2\)

\(f(其他)=INF\)

状态转移方程

然后我们按照情况讨论(推柿子)即可:

情况一:不增加牛舍数量

设 \(tmp=cow[i].x-cow[i-1].x\)(前后两列奶牛的横坐标之差)

\(f(i,j,1)=min(f(i-1,j,1),f(i-1,j,4))+tmp\)

\(f(i,j,2)=min(f(i-1,j,2),f(i-1,j,4))+tmp\)

\(f(i,j,3)=f(i-1,j,3)+2\times tmp\)

\(f(i,j,4)=f(i-1,j,4)+2\times tmp\)

解释一下:当不新增牛舍时,只能延长原本存在的牛舍,易得上面的递推式。

情况二:增加一个牛舍

设:

  1. \(best1=min(f(i-1,j-1,1),f(i-1,j-1,2))\)
  2. \(best2=min(f(i-1,j-1,3),f(i-1,j-1,4))\)
  3. \(best=min(best1,best2)\)

\(f(i,j,1)=min(f(i,j,1),best+1)\)

\(f(i,j,2)=min(f(i,j,2),best+1)\)

\(f(i,j,3)=min(f(i,j,3),best+2)\)

\(f(i,j,4)=min(f(i,j,4),min(best1,f(i-1,j-1,4))+(tmp+1))\)

再来解释一下:首先的预处理就是为了方便处理,仅是个人习惯不用过多纠结。

如果能够增加一个牛舍,那么对于状况 \(1,2,3\) 均可以直接原地增加一个牛舍,不用管前面是什么状况。

但是对于状况 \(4\),只能增加一个牛舍的情况将十分尴尬,只能从前面延长一个牛舍,再本地新增一个牛舍。

显然只能从上一次的状况 \(1,2,4\) 推来。

情况三:增加两个牛舍

\(f(i,j,4)=min(f(i,j,4),min\{f(i,j-2,1\)~\(4)\}+2)\)

显然,只有情况四需要新增两个牛舍(其他一个就够了),所以易得上方程。

答案统计

易得:

\(ans=min_{1\leq p\leq 4}\{f(n,k,p)\}\)

代码实现

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#define N 1010
#define INF 0x3f3f3f3f
using namespace std; int n,k,b,cnt=0;
int f[N][N][10];
struct node{
int x,y;
}a[N];
struct Cow{
int x,t;
}cow[N]; int read(){
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
return x*f;
} bool cmp(node a,node b){
if(a.x!=b.x) return a.x<b.x;
return a.y<b.y;
} void build(){
for(int i=1;i<=n;i++){
if(a[i].x==a[i-1].x)
cow[cnt].t=3;
else cow[++cnt].t=a[i].y,cow[cnt].x=a[i].x;
}
return;
} void dp(){
memset(f,0x3f,sizeof(f));
f[0][0][0]=0;
if(cow[1].t==1) f[1][1][1]=1;
else if(cow[1].t==2) f[1][1][2]=1;
f[1][1][3]=f[1][2][4]=2; for(int i=2;i<=cnt;i++){
for(int j=1;j<=k;j++){
int tmp=cow[i].x-cow[i-1].x; if(cow[i].t==1) f[i][j][1]=min(f[i-1][j][1],f[i-1][j][4])+tmp;
if(cow[i].t==2) f[i][j][2]=min(f[i-1][j][2],f[i-1][j][4])+tmp;
f[i][j][3]=f[i-1][j][3]+2*tmp;
f[i][j][4]=f[i-1][j][4]+2*tmp; if(j==1) continue;
int best1=min(f[i-1][j-1][1],f[i-1][j-1][2]);
int best2=min(f[i-1][j-1][3],f[i-1][j-1][4]);
int best=min(best1,best2);
if(cow[i].t==1) f[i][j][1]=min(f[i][j][1],best+1);
if(cow[i].t==2) f[i][j][2]=min(f[i][j][2],best+1);
f[i][j][3]=min(f[i][j][3],best+2);
f[i][j][4]=min(f[i][j][4],min(f[i-1][j-1][4],best1)+(tmp+1)); if(j==2) continue;
f[i][j][4]=min(f[i][j][4],min(min(f[i-1][j-2][1],f[i-1][j-2][2]),min(f[i-1][j-2][3],f[i-1][j-2][4]))+2);
}
}
} int main(){
//freopen("lazy.in","r",stdin);
//freopen("lazy.out","w",stdout);
n=read(),k=read(),b=read();
for(int i=1;i<=n;i++)
a[i].y=read(),a[i].x=read();
sort(a+1,a+n+1,cmp);
build();
dp();
printf("%d\n",min(min(f[cnt][k][1],f[cnt][k][2]),min(f[cnt][k][3],f[cnt][k][4])));
//fclose(stdin);fclose(stdout);
return 0;
}

完结撒花

最新文章

  1. SharePoint 2013 为站点配置基于主机标头的双域名
  2. hashmap先按照value从大到小排序,value相等时按照key从小到大排序
  3. phpcms二层栏目下拉和当前栏目高亮
  4. Quartz框架简介
  5. [转发]UML类图符号 各种关系说明以及举例
  6. 解决Win10服务主机本地系统网络受限
  7. Design Pattern :Factory and Reflect in java
  8. 对线程调度中Thread.sleep(0)的深入理解
  9. 【C++】非原创|统计代码覆盖率(一:C++)
  10. DataSetToList 和 DataTableTolist 转换
  11. 为过程或函数sp_Adduser指定了过多的参数
  12. C各个类型的大小
  13. 简单谈谈js中的MVC
  14. session and cooike
  15. Infopath 2013 通过UserProfileService读取AD用户信息
  16. The server time zone value &#39;&#214;&#208;&#185;&#250;&#177;&#234;&#215;&#188;&#202;&#177;&#188;&#228;&#39; is unrecognized or represents more than one time zone问题解决
  17. [JavaScript] 的异步编程之手写一个Gernerator的例子
  18. OpenCV学习资源库
  19. Maven的国内镜像(解决jar下载过慢)
  20. DXT 图片压缩(DXTC/DirectX Texture Compression Overview)

热门文章

  1. c#后台代码请求访问api接口
  2. 在程序开发中,++i 与 i++的区别在哪里?
  3. C1853 编译器错误:fatal error C1853: &#39;pjtname.pch&#39; precompiled header file is from a previous
  4. BeetleX之webapi使用入门
  5. Hadoop框架:NameNode工作机制详解
  6. Git命令diff格式详解
  7. Windows下的git服务器搭建
  8. 三门峡6378.7939(薇)xiaojie:三门峡哪里有xiaomei
  9. Linux系统编程 —线程同步概念
  10. C语言从1打印到100再打印到1该如何编写?我只服最后一种写法!