HDU 5473 There was a kingdom 凸包 DP
题意:
给出平面上n个点的坐标,选k个点,使得这k个点围起来的面积最大.
分析:
参考了 叉姐的分析 和 不慌不忙菊苣的代码
思路我都懂,但是DP的部分还是不太会写.
我体会了一下其中含义,也许这样可能会好理解一点:
因为求出来的凸包的点数是固定的,所能选的点数也是固定的,那么不选的点的数量也是固定的.
可以反过来考虑:少选一个点,就要损失凸包上的一块面积.
假设\(d(i,j)\)表示考虑了前\(i\)个点,选了\(j\)个点,所损失的最少面积.
第\(i\)个点的前一个点是\(i'\),损失的面积为\(S_{cut}\),那么\(d(i,j)=min(d(i,j),d(i',j-1)+S_{cut})\)
最后答案就是凸包总面积减去最后损失的最小面积.
损失的面积是一小块一小块三角形累加起来的.
上个图片仅供参考:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn = 100 + 10;
struct Point
{
LL x, y;
Point(LL x = 0, LL y = 0) : x(x), y(y) {}
void read() { scanf("%lld%lld", &x, &y); }
};
Point operator - (const Point& A, const Point& B) {
return Point(A.x - B.x, A.y - B.y);
}
bool operator < (const Point& A, const Point& B) {
return A.x < B.x || (A.x == B.x && A.y < B.y);
}
LL Cross(const Point& A, const Point& B) {
return A.x * B.y - A.y * B.x;
}
vector<Point> p, con;
vector<Point> ConvexHull() {
sort(p.begin(), p.end());
int n = p.size();
vector<Point> ch(n);
int m = 0;
for(int i = 0; i < n; i++) {
while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) < 0) m--;
ch[m++] = p[i];
}
int k = m;
for(int i = n - 2; i >= 0; i--) {
while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) < 0) m--;
ch[m++] = p[i];
}
if(n > 1) m--;
ch.resize(m);
return ch;
}
int n, k;
LL d[maxn][maxn];
bool vis[maxn];
int main()
{
//freopen("in.txt", "r", stdin);
int _; scanf("%d", &_);
for(int __ = 1; __ <= _; __++) {
scanf("%d%d", &n, &k);
p.resize(n);
for(int i = 0; i < n; i++) p[i].read();
con = ConvexHull();
int sz = con.size();
if(sz <= 2 || k <= 2) { printf("0\n"); continue; }
LL totarea = 0;
for(int i = 2; i < sz; i++) totarea += Cross(con[i-1]-con[0], con[i] - con[0]);
if(k >= sz) {
printf("%lld\n", totarea);
continue;
}
LL ans = 0x3f3f3f3f3f3f3f3f;
memset(vis, false, sizeof(vis));
int times = min(10 * n / k, sz);
while(times--) {
int s = rand() % sz;
while(vis[s]) s = rand() % sz;
vis[s] = true;
memset(d, 0x3f, sizeof(d));
d[0][0] = 0;
for(int i = 1; i <= sz; i++) {
int p0 = (s + i) % sz;
LL cut = 0;
for(int j = i - 1; j >= 0; j--) {
int p2 = (s + j) % sz;
int p1 = (p2 + i) % sz;
cut += Cross(con[p1] - con[p0], con[p2] - con[p0]);
for(int l = k; l > 0; l--)
d[i][l] = min(d[i][l], d[j][l-1] + cut);
}
}
ans = min(ans, d[sz][k]);
}
printf("Case #%d: %lld\n", __, totarea - ans);
}
return 0;
}
HDU 5473 There was a kingdom 凸包 DP的更多相关文章
- hdu 5025 Saving Tang Monk 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- HDU 3341 Lost's revenge AC自动机+dp
Lost's revenge Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- HDU 2457 DNA repair(AC自动机+DP)题解
题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...
- Codeforces 835 F Roads in the Kingdom(树形dp)
F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...
- HDU 1028 Ignatius and the Princess III dp整数划分
http://acm.hdu.edu.cn/showproblem.php?pid=1028 dp[i][j]表示数值为i,然后最小拆分的那个数是j的时候的总和. 1 = 1 2 = 1 + 1 . ...
- HDU 1025 Constructing Roads In JGShining's Kingdom(DP+二分)
点我看题目 题意 :两条平行线上分别有两种城市的生存,一条线上是贫穷城市,他们每一座城市都刚好只缺乏一种物资,而另一条线上是富有城市,他们每一座城市刚好只富有一种物资,所以要从富有城市出口到贫穷城市, ...
- hdu 1025:Constructing Roads In JGShining's Kingdom(DP + 二分优化)
Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65 ...
- HDU 1025 Constructing Roads In JGShining's Kingdom (DP)
Problem Description JGShining's kingdom consists of 2n(n is no more than 500,000) small cities which ...
随机推荐
- @Primary 使用
造轮子的一个小小的发现 当一个接口被两个service实现时,controller调用接口实现功能,会报错,提示开发者指定service,官方是建议你使用@Qualifier来区分的,但是,总有另一种 ...
- 现阶段github上的emysql编译无法通过的问题
最近在写db引擎,今天用到了emysql,找到https://github.com/Eonblast/Emysql,拽下来,然后发现竟然编译不通过~~去网上找了下资料,在 http://erlang. ...
- Java面向对象(接口、多态)
面向对象 今日内容介绍 u 接口 u 多态 第1章 接口 1.1 接口概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的 ...
- css中伪类/伪元素详解
一.伪类和伪元素 伪类和伪元素都是用来修饰不在文档树中的部分,区别在于, 伪类用于当已有元素处于的某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的(如:hover/:active). ...
- [拾零]C语言的数组指针
为了强化记忆,从而写笔记保留. 数组指针,顾名思义,是在说一个指针,这个指针是指向数组的. 区别于指针数组 int* p[5] = NULL; //指针数组 基类型 int* int (*p)[5] ...
- 【extjs6学习笔记】Mastering Ext JS, 2nd Edition
我不知道在别人看来,我是什么样的人:但在我自己看来,我不过就象是一个在海滨玩耍的小孩,为不时发现比寻常更为光滑的一块卵石或比寻常更为美丽的一片贝壳而沾沾自喜,而对于展现在我面前的浩瀚的真理的海洋,却全 ...
- freopen()函数
freopen函数通过实现标准I/O重定向功能来访问文件,而fopen函数则通过文件I/O来访问文件. freopen函数在算法竞赛中常被使用.在算法竞赛中,参赛者的数据一般需要多次输入,而为避免重复 ...
- UVA 536 TreeRocvery 树重建 (递归)
根据先序历遍和中序历遍输出后序历遍,并不需要真的建树,直接递归解决 #include<cstdio> #include<cstring> ; char preOrder[N]; ...
- Android(java)学习笔记121:BroadcastReceiver之 自定义广播
广播使用: 电台:对外发送信号.---------电台发送广播(可以自定义) 收音机:接收电台的信号.-----广播接收者 这里,我们就说明自定 ...
- [论文理解] Connectionist Text Proposal Network
Connectionist Text Proposal Network 简介 CTPN是通过VGG16后在特征图上采用3*3窗口进行滑窗,采用与RPN类似的anchor机制,固定width而只预测an ...