Brush (IV) LightOJ - 1018
题意:平面上有一些点,每刷一次可以把同一条直线上的点都刷光,问最少几次把所有点刷光。
方法:
显然是一个状态压缩dp。ans[S]表示把S集合中点刷掉的最少次数。最开始想到的方法是如果S中只有一个或两个点,那么ans[S]=1。否则枚举S中任意两点i,j作为直线上的点,并算出经过i,j的直线还过S中其他多少个点,那么ans[S]=min(ans[S],ans[S去掉那条直线经过的所有点]+1)。自然而然的就想到应该预处理出过i,j两点的直线过的其他点的集合,只需要枚举i,j和另外一个点再判是否共线即可。
这里需要用到判三点共线:https://www.zybang.com/question/ca7778a2e315afb588629121177b6772.html
A(x1,y1),B(x2,y2),C(x3,y3),则(x2-x1)×(y3-y2)=(x3-x2)×(y2-y1)
但是,这样时间复杂度是$O(T*n^3*2^n)$,还是太慢了。
观察一下可以发现:由于一个集合中所有点早晚都要刷掉,只需要指定任意一个点作为直线上的点,再枚举另一个点就行了。
那么,复杂度降低到$O(T*n^2*2^n)$。对于单组数据复杂度已经可以接受,但是由于T比较大,还是不能通过。
接下来开始卡常:
1.把循环的dp改成记忆化搜索能快许多,因为最终状态不一定需要其他所有状态的答案。
2.在开始时预处理出每个集合S的所有元素,而不是每次枚举编号判断是否在S内
3.常规(meiyong):快读,预处理左移
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int x[],y[];
int T,TT,n,fff;
int ans[];
int tmp[][];
int left[];
int G[][];
void read(int&x)
{
x=;
char ch=getchar();fff=;
while(ch<''||ch>'')
{
if(ch=='-') fff=-;
ch=getchar();
}
while(ch>=''&&ch<='') x=(x<<)+(x<<)+ch-'',ch=getchar();
x*=fff;
}
int main()
{
int i,j,k,t1,t2;
for(i=;i<;i++) left[i]=(<<i);
for(i=;i<;i++)
for(k=;k<;k++)
if(i&left[k])
G[i][++G[i][]]=k;
read(T);
for(TT=;TT<=T;TT++)
{
read(n);
for(i=;i<n;i++)
read(x[i]),read(y[i]);
//memset(tmp,0,sizeof(tmp));
for(i=;i<n;i++)
for(j=i+;j<n;j++)
{
tmp[i][j]=;
t1=x[j]-x[i];
t2=y[j]-y[i];
for(k=;k<n;k++)
if(t1*(y[k]-y[j])==(x[k]-x[j])*t2)
tmp[i][j]|=left[k];
tmp[j][i]=tmp[i][j];
}
//memset(ans,0x3f,sizeof(ans));
ans[]=;
for(i=;i<left[n];i++)
{
if(__builtin_popcount(i)<=)
ans[i]=;
else
{
ans[i]=0x3f3f3f3f;
//每个点都迟早要被刷,因此枚举任意一个点作为直线上点即可,不用枚举两个
j=G[i][];
for(k=;k<=G[i][];k++)
ans[i]=min(ans[i],ans[i^(tmp[j][G[i][k]]&i)]+);
}
}
printf("Case %d: %d\n",TT,ans[left[n]-]);
}
return ;
}
Brush (IV) LightOJ - 1018的更多相关文章
- Lightoj 1018 - Brush (IV)
1018 - Brush (IV) PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Muba ...
- 1018 - Brush (IV)
1018 - Brush (IV) PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Muba ...
- Brush (III) LightOJ - 1017
Brush (III) LightOJ - 1017 题意:有一些点,每刷一次可以将纵坐标在区间(y1,y1+w)范围内的所有点刷光,y1为任何实数.最多能刷k次,求最多共能刷掉几个点. 先将点按照纵 ...
- [LightOJ 1018]Brush (IV)[状压DP]
题目链接:http://lightoj.com/volume_showproblem.php? problem=1018 题意分析:平面上有不超过N个点,如今能够随意方向划直线将它们划去,问:最少要划 ...
- (状压) Brush (IV) (Light OJ 1018)
http://www.lightoj.com/volume_showproblem.php?problem=1018 Mubashwir returned home from the contes ...
- Light OJ 1018 - Brush (IV)
题目大意: 一个二维平面上有N个点,一把刷子,刷一次可以把一条线上的所有点都刷掉.问最少刷多少次,可以把全部的点都刷完 状态压缩DP, 用记忆化搜索来写, 需要有个优化不然会超时. ===== ...
- Light oj 1018 - Brush (IV) 状态压缩
题目大意: 给出n个点的坐标,求至少画多少掉直线才能连接所有点. 题目思路:状态压缩 首先经行预处理,求出所有状态下,那些点不在该状态内 以任意两点为端点求出这条直线的状态 枚举所有状态,找出不在当前 ...
- lightoj 1018 dp
题目链接:http://lightoj.com/volume_showproblem.php?problem=1018 #include <cstdio> #include <cst ...
- LightOJ1018 Brush (IV)(状压DP)
题目大概说一个平面有n个灰尘,可以用一把刷子直直刷过去清理直线上的所有灰尘,问最少要刷几下才能清理完所有灰尘. 首先怎么刷其实是可以确定的,或者说直线有哪些是可以确定的,而最多就有C(n,2)条不一样 ...
随机推荐
- 写码时应该缩进使用 tab 还是空格?
对于程序员来说,其实Tab和空格远远不只是“立场”问题那么简单. 在不同的编辑器里tab的长度可能不一致,所以在一个编辑器里用tab设置缩进后,在其它编辑器里看可能缩进就乱了.空格不会出现这个问题,因 ...
- Chrome浏览器 js 关闭窗口失效解决方法
//获取元素ID var DelHtml = document.getElementById("imgdel"); //alert(DelHtml); //添加点击事件 DelHt ...
- C#令人迷惑的DateTime:世界标准时间还是本地时间?
先来看一段代码: 复制内容到剪贴板程序代码 DateTime time = DateTime.Parse("2013-07-05 00:00:00");Console.WriteL ...
- 组合式+迭代式+链式 MapReduce
1.迭代式mapreduce 一些复杂的任务难以用一次mapreduce处理完成,需要多次mapreduce才能完成任务,例如Pagrank,Kmeans算法都需要多次的迭代,关于mapreduce迭 ...
- Phoenix(SQL On HBase)安装和使用报告
一.为什么使用Phoenix二.安装Phoenix2.1 兼容问题?2.2 编译CDH版本的Phoenix2.3 安装Phoenix到CDH环境中三.Phoenix的使用3.1 phoenix的4种调 ...
- c3p0+spring
1. 首先是jdbc.properties属性文件的编写,便于数据库移植: datasource.driverClassName=oracle.jdbc.driver.OracleDriverdata ...
- 今日头条上看到的js面试题和答案
用js判断字符中每个字符出现的次数, 答案是var info = arr.split('').reduce((a,b)=>(console.log(a,b),a[b]++ || (a[b]=1) ...
- js Date.parse()兼容性问题
最近在做一个日历控件,网上copy了一段代码然后自己又改改. 标准浏览器下正常,结果ie全部不支持,搞不懂,原来Date.parse在IE下有兼容性问题 //beginData格式为'yyyy-mm- ...
- 更改scroll样式
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 2px; height: 80%; background: #fff; } /*定 ...
- MYSQL初级学习笔记四:查询数据的操作DQL(SELECT基本形式)(26-35)
知识点六:查询数据的操作DQL(SELECT基本形式)(26-35) CREATE DATABASE IF NOT EXISTS cms DEFAULT CHARACTER SET utf8; USE ...