[动态规划]P1378 油滴扩展
题目描述
在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界。必须等一个油滴扩展完毕才能放置下一个油滴。那么应该按照怎样的顺序在这N个点上放置油滴,才能使放置完毕后所有油滴占据的总体积最大呢?(不同的油滴不会相互融合)
注:圆的面积公式V=pirr,其中r为圆的半径。
输入输出格式
输入格式:
第1行一个整数N。
第2行为长方形边框一个顶点及其对角顶点的坐标,x,y,x’,y’。
接下去N行,每行两个整数xi,yi,表示盒子的N个点的坐标。
以上所有的数据都在[-1000,1000]内。
输出格式:
一行,一个整数,长方形盒子剩余的最小空间(结果四舍五入输出)
输入输出样例
输入样例#1:
2
20 0 10 10
13 3
17 7
输出样例#1:
50
解释:
---------题解(Gelphue),老天爷都找不到更良心的题解了---------
对于这道题(好久没写搜索了呢),对答案起决定性因素的是点拓展的顺序(DFS就是在搜索TA),其次就是对题中各种要求的处理,列表:
1.对于所给长方形,为了统一形式,设点kup为左上角,lap为右下角,且横坐标为Y,纵坐标为X(横坐标为j,纵坐标为i);处理方式为:
cin >> n; cin >> kup.x >> kup.y >> lap.x >> lap.y; if (kup.x > lap.x) swap(kup.x, lap.x);//保证左上角的横坐标严格小于右下角的横坐标 if (kup.y > lap.y) swap(kup.y, lap.y);//保证左上角的纵坐标严格小于右下角的纵坐标2.对于输入的N个点以及左上,右下坐标,全部自减点kup(坐上坐标),以使长方形的左上角与坐标原点重合,即所有点都在第四象限类,每一的点拓展出去的半径r初始化为0,处理方案为:
for (int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y, a[i].x -= kup.x, a[i].y -= kup.y, a[i].r = 0; lap.x -= kup.x, lap.y -= kup.y;3.预处理每两个点之间的距离,用二维数组贮存,处理方案为:
for (int i = 1; i <= n; i++) { for (int j = 1; j < i; j++) dist[i][j] = sqrt(pow(a[i].x - a[j].x, 2) + pow(a[i].y - a[j].y, 2)), dist[j][i] = dist[i][j];//a[i]到a[j] 和 a[j]到a[i] 的距离相同 }4.用DOUBLE anso表示在不同的拓展顺序中能得到的最大半径和(为 a[1].r^2+a[2].r^2+...+a[N].r^2),输出则用长方形面积(lap.xlap.y)减去总共圆的面积(为 ansoPi),处理方案为(推导过程就不必说了吧):
dfs(1); cout << (int)(lap.x*lap.y - floor(anso*Pi + 1.0 / 2)) << endl;5.先上一份dfs()的代码:
void dfs(int d) { if (d > n) { double tem_as = 0.0;//统计在这种顺序下的半径平方和 for (int i = 1; i <= n; i++) tem_as += a[i].r_R;//为了优化时间复杂度,把a[i].r*a[i].r单独作为一个成员变量(a[i].r_R) anso = max(anso, tem_as);//更性较大值 } for (int i = 1; i <= n; i++) if (!use[i])//还没有被搜过 { use[i] = 1; {//以下高能,稍后解释*1 a[i].r = min(min(a[i].x, lap.x - a[i].x), min(a[i].y, lap.y - a[i].y)); for (int k = 1; k <= n; k++) if (use[k]&& k!=i) { a[i].r = min(a[i].r, dist[i][k] - a[k].r); } if (a[i].r < 0) a[i].r = 0; } a[i].r_R = a[i].r*a[i].r;//更新半径平方 dfs(d + 1);//进行下一层搜索 use[i] = 0; } } /*1:解释在这儿:对于正在搜的点,要满足a[i]在长方形以内,则需要满足 a[i].x-a[i].r>=0, a[i].y-a[i].r>=0, a[i].x+a[i].r<=lap.x, a[i].y+a[i].r<+lap.y. 所以有了这一句话: a[i].r = min(min(a[i].x, lap.x - a[i].x), min(a[i].y, lap.y - a[i].y)); ;然后就要找所有已经找过的点(a[k])一一和a[i]进行比较,其中a[i].r必须要满足: a[i].r+a[k].r<=dist[i][k], 至于为什么,这里扔一张图 */
好了,综上所述,完整的代码在这里
// 动态规划专题(zx).cpp : 定义控制台应用程序的入口点。
//Strengthen self without stopping, and hold world with virtue
//
#include "stdafx.h"
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Pi (double)3.14159265358
#define redef ios::sync_with_stdio(false),cout.tie(NULL);
int n;
double dist[7][7];
double anso=0;
bool use[7];
struct pl
{
double x, y, r;
double r_R;//r_R=:r*r;
bool operator < (const pl&oth)const
{
return (x <= oth.x && y <= oth.y);
}
}a[7], kup, lap;
void dfs(int d)
{
if (d > n)
{
double tem_as = 0.0;
for (int i = 1; i <= n; i++)
tem_as += a[i].r_R;
anso = max(anso, tem_as);
}
for (int i = 1; i <= n; i++)
if (!use[i])
{
use[i] = 1;
{
a[i].r = min(min(a[i].x, lap.x - a[i].x), min(a[i].y, lap.y - a[i].y));
for (int k = 1; k <= n; k++)
if (use[k]&& k!=i)
{
a[i].r = min(a[i].r, dist[i][k] - a[k].r);
}
if (a[i].r < 0) a[i].r = 0;
}
a[i].r_R = a[i].r*a[i].r;
dfs(d + 1);
use[i] = 0;
}
}
int main()
{
redef cin >> n;
cin >> kup.x >> kup.y >> lap.x >> lap.y;
{
if (kup.x > lap.x) swap(kup.x, lap.x);
if (kup.y > lap.y) swap(kup.y, lap.y);
}
for (int i = 1; i <= n; i++)
cin >> a[i].x >> a[i].y,
a[i].x -= kup.x,
a[i].y -= kup.y,
a[i].r = 0;
lap.x -= kup.x, lap.y -= kup.y;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j < i; j++)
dist[i][j] = sqrt(pow(a[i].x - a[j].x, 2) + pow(a[i].y - a[j].y, 2)),
dist[j][i] = dist[i][j];
}
dfs(1);
cout << (int)(lap.x*lap.y - floor(anso*Pi + 1.0 / 2)) << endl;
return 0;
}
[动态规划]P1378 油滴扩展的更多相关文章
- 洛谷 P1378 油滴扩展 改错
P1378 油滴扩展 题目描述 在一个长方形框子里,最多有\(N(0≤N≤6)\)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油 ...
- 洛谷P1378 油滴扩展
P1378 油滴扩展 题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完 ...
- 洛谷 P1378 油滴扩展
P1378 油滴扩展 题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完 ...
- P1378 油滴扩展——搜索小记
P1378 油滴扩展 记得这道题好久以前(好像是上个学期?) 就想做了,但是看着里面的半径边界好像很难处理就没做(主要是当时刚学OI(菜还给自己找借口)): 今天上午一直研究SG函数,做的都自闭了,晚 ...
- 洛谷P1378 油滴扩展(搜索)
洛谷P1378 油滴扩展 直接暴力搜索更新答案就可以了. 时间复杂度为 \(O(n!)\) . #include<stdio.h> #include<stdlib.h> #in ...
- 洛谷 P1378 油滴扩展 Label:搜索
题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完毕才能放置下一个油滴. ...
- P1378 油滴扩展
题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完毕才能放置下一个油滴. ...
- P1378 油滴扩展 dfs回溯法
题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完毕才能放置下一个油滴. ...
- luogu P1378 油滴扩展
题目描述 在一个长方形框子里,最多有N(0≤N≤6)个相异的点,在其中任何一个点上放一个很小的油滴,那么这个油滴会一直扩展,直到接触到其他油滴或者框子的边界.必须等一个油滴扩展完毕才能放置下一个油滴. ...
随机推荐
- bzoj 2243 [SDOI2011]染色(树链剖分+线段树合并)
[bzoj2243][SDOI2011]染色 2017年10月20日 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询 ...
- MySQL基础函数
MySQL数据库提供了很多函数包括: 数学函数: 字符串函数: 日期和时间函数: 条件判断函数: 系统信息函数: 加密函数: 格式化函数: 一.数学函数 数学函数主要用于处理数字,包括整型.浮点数等. ...
- 我的第一个python web开发框架(13)——工具函数包说明(四)
string_helper.py是字符串操作包,主要对字符串进行检查.过滤和截取等处理. #!/usr/bin/evn python # coding=utf-8 import re def chec ...
- struts2国际化相关问题
国际化资源文件的方式: Action范围的 包范围的 临时的 全局的(推荐) 一.配置全局的国际化资源文件 1.在类路径下,创建国际化资源文件 baseName.properties baseName ...
- iOS 11更新后以及iPhone X推出后工程中遇到的问题及适配
1.UITableView滑动时右侧的滑动条忽长忽短的乱跳以及MJRefresh上拉刷新死循环 这是因为tableView在iOS11默认使用Self-Sizing,tableView的estimat ...
- 紧跟腾讯大王卡:B站2233卡“基友号”即将上线
来自B站官方的消息显示,B站在近期也将推出"基友号"功能,功能的内容是通话免费,考虑到这类互联网套餐都是中国联通在运营,因此在内容上可能也会效仿腾讯大王卡实现免费通话. 目前,B站 ...
- Chinese Rings
Chinese Rings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Cup
Cup Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissio ...
- html5 postMessage解决跨域、跨窗口消息传递[转载]
原文:http://www.cnblogs.com/dolphinX/p/3464056.html 一些麻烦事儿 平时做web开发的时候关于消息传递,除了客户端与服务器传值还有几个经常会遇到的问题 1 ...
- grid 布局
display:grid 是一种新的布局方式,旧的布局方式通常有副作用,例如float(需要额外修复浮动)或者inline-block(两个元素之间的空格问题) 把父元素定义为grid,就像表格一 ...