题意:平面上有一些点,每刷一次可以把同一条直线上的点都刷光,问最少几次把所有点刷光。

方法:

显然是一个状态压缩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):快读,预处理左移

错误记录:

1.复杂度错误,$O(T*n^3*2^n)$

2.被卡常,用http://blog.csdn.net/kijamesqi/article/details/50533691的方法卡过去

 #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的更多相关文章

  1. Lightoj 1018 - Brush (IV)

    1018 - Brush (IV)    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Muba ...

  2. 1018 - Brush (IV)

    1018 - Brush (IV)    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Muba ...

  3. Brush (III) LightOJ - 1017

    Brush (III) LightOJ - 1017 题意:有一些点,每刷一次可以将纵坐标在区间(y1,y1+w)范围内的所有点刷光,y1为任何实数.最多能刷k次,求最多共能刷掉几个点. 先将点按照纵 ...

  4. [LightOJ 1018]Brush (IV)[状压DP]

    题目链接:http://lightoj.com/volume_showproblem.php? problem=1018 题意分析:平面上有不超过N个点,如今能够随意方向划直线将它们划去,问:最少要划 ...

  5. (状压) Brush (IV) (Light OJ 1018)

    http://www.lightoj.com/volume_showproblem.php?problem=1018   Mubashwir returned home from the contes ...

  6. Light OJ 1018 - Brush (IV)

    题目大意:     一个二维平面上有N个点,一把刷子,刷一次可以把一条线上的所有点都刷掉.问最少刷多少次,可以把全部的点都刷完 状态压缩DP, 用记忆化搜索来写, 需要有个优化不然会超时. ===== ...

  7. Light oj 1018 - Brush (IV) 状态压缩

    题目大意: 给出n个点的坐标,求至少画多少掉直线才能连接所有点. 题目思路:状态压缩 首先经行预处理,求出所有状态下,那些点不在该状态内 以任意两点为端点求出这条直线的状态 枚举所有状态,找出不在当前 ...

  8. lightoj 1018 dp

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1018 #include <cstdio> #include <cst ...

  9. LightOJ1018 Brush (IV)(状压DP)

    题目大概说一个平面有n个灰尘,可以用一把刷子直直刷过去清理直线上的所有灰尘,问最少要刷几下才能清理完所有灰尘. 首先怎么刷其实是可以确定的,或者说直线有哪些是可以确定的,而最多就有C(n,2)条不一样 ...

随机推荐

  1. error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token

    头文件函数声明少了“:(分号)”

  2. 全局钩子 实例(不使用DLL和使用DLL两种)

    大家应该都知道,全局消息钩子要依赖于一个DLL才能够正常工作.于是呢,我也就理所当在地认为全局钩子都要依赖于一个DLL才能正常工作的,我想大部分人肯定和我一样也这么认为的. 但实际上不是这样的.有某些 ...

  3. storage engine option for directoryPerDB

    Requested option conflicts with current storage engine option for directoryPerDB; you requested true ...

  4. 使用cwRsync在Windows的目录之间增量同步文件

    http://www.qiansw.com/using-cwrsync-in-the-windows-directory-between-the-incremental-synchronization ...

  5. install build tools 25.0.2 and sync the project

    install build tools 25.0.2 and sync the project in android studio bundle.gradle,将buildToolsVersion修改 ...

  6. django rest_framework swagger使用案例

    环境准备 环境要求: python3 django2 pip3 模块安装: pip3 install django-rest-framework pip3 install django-rest-sw ...

  7. CodeForces - 55D Beautiful numbers —— 数位DP

    题目链接:https://vjudge.net/problem/CodeForces-55D D. Beautiful numbers time limit per test 4 seconds me ...

  8. SpringBoot发送简单文本邮件

    1.pom.xml添加 spring-boot-starter-mail 依赖 <dependency> <groupId>org.springframework.boot&l ...

  9. 执行sql语句异常...需要的参数与提供的值个数不匹配

    执行mysql语句时,出现以下错误时. 看错误提示,提示说你的sql语句只需要5个参数,而你提供了8个值value,你确定你确实需要8个参数,而你的sql语句却提示说只需要5个参数 这时,请仔细检查一 ...

  10. 关于布局(Layout)的一切

    之前在布局中有很多问题也有很多经验,遗憾都没记下来.现在一点点记下一些东西. 1.外层用LinearLayout的话,常常把orientation设成vertical, android:orienta ...