Mubashwir returned home from the contest and got angry after seeing his room dusty. Who likes to see a dusty room after a brain storming programming contest? After checking a bit he found an old toothbrush in his room. Since the dusts are scattered everywhere, he is a bit confused what to do. So, he called Shakib. Shkib said that, 'Use the brush recursively and clean all the dust, I am cleaning my dust in this way!'

So, Mubashwir got a bit confused, because it's just a tooth brush. So, he will move the brush in a straight line and remove all the dust. Assume that the tooth brush only removes the dusts which lie on the line. But since he has a tooth brush so, he can move the brush in any direction. So, he counts a move as driving the tooth brush in a straight line and removing the dusts in the line.

Now he wants to find the maximum number of moves to remove all dusts. You can assume that dusts are defined as 2D points, and if the brush touches a point, it's cleaned. Since he already had a contest, his head is messy. That's why he wants your help.

Input

Input starts with an integer T (≤ 1000), denoting the number of test cases.

Each case starts with a blank line. The next line contains three integers N (1 ≤ N ≤ 16)N means that there are N dust points. Each of the next N lines will contain two integers xi yi denoting the coordinate of a dust unit. You can assume that (-1000 ≤ xi, yi ≤ 1000) and all points are distinct.

Output

For each case print the case number and the minimum number of moves.

Sample Input

Output for Sample Input

2

3

0 0

1 1

2 2

3

0 0

1 1

2 3

Case 1: 1

Case 2: 2

题目大意:
 
给你n个点, 求最少的直线将所有的点都覆盖
 
 
记忆化搜索:
 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef unsigned long long LL;
#define met(a,b) (memset(a,b,sizeof(a)))
const int INF = 1e9+;
const int maxn = ;
const int MOD = ; struct node
{
int x, y;
} a[]; int dp[(<<)], n;
int Line[][];
///Line[i][j] 代表与线段ij共线的点 int DFS(int sta)
{
if(dp[sta]!=-) return dp[sta]; dp[sta] = INF;
int cnt=;
for(int i=; i<n; i++)
if(sta&(<<i)) cnt++; if(cnt==) return dp[sta]=;
else if(cnt<=) return dp[sta]=; for(int i=; i<n; i++)
{
if(sta&(<<i))///第i个物品
{
for(int j=i+; j<n; j++)
{
int w = (sta|Line[i][j]) - Line[i][j];
dp[sta] = min(dp[sta], DFS(w)+);
}
break;
///优化,只需找到sta中的一个点即可, Line[i][j]会将所有的i到i后面的点都遍历一遍的
}
}
return dp[sta];
} int main()
{
int T, iCase = ;
scanf("%d", &T); while(T --)
{
int i, j, k, K;
scanf("%d", &n); K = (<<n)-;
met(dp, -);
met(Line, );
for(i=; i<n; i++)
{
scanf("%d%d", &a[i].x, &a[i].y);
Line[i][i] = (<<i);
} for(i=; i<n; i++)
for(j=i+; j<n; j++)
for(k=; k<n; k++)
{ ///判断三点是否共线
if( (a[i].x-a[k].x)*(a[i].y-a[j].y) == (a[i].x-a[j].x)*(a[i].y-a[k].y) )
Line[i][j] += (<<k);
} printf("Case %d: %d\n", iCase++, DFS(K));
}
return ;
}

先预处理出来每条线段,对每一个状态选择两个不在状态的点,然后画以两个点为端点的线,来进行状态转移

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef unsigned long long LL;
#define met(a,b) (memset(a,b,sizeof(a)))
const int INF = 1e9+;
const int maxn = ;
const int MOD = ; struct node
{
int x, y;
}a[]; vector<int>G[(<<)];
int dp[(<<)], n;
int Line[][];
///Line[i][j] 代表与线段ij共线的点 int main()
{
int T, iCase = , i, j; for(i=; i<(<<); i++)
for(j=; j<; j++)
{
if((i&(<<j))==)
G[i].push_back(j);
} scanf("%d", &T); while(T --)
{
int k, K;
scanf("%d", &n); K = (<<n)-;
met(dp, INF);
met(Line, );
for(i=; i<n; i++)
{
scanf("%d%d", &a[i].x, &a[i].y);
Line[i][i] = (<<i);
} for(i=; i<n; i++)
for(j=i+; j<n; j++)
for(k=; k<n; k++)
{ ///判断三点是否共线
if( (a[i].x-a[k].x)*(a[i].y-a[j].y) == (a[i].x-a[j].x)*(a[i].y-a[k].y) )
Line[i][j] += (<<k);
} dp[] = ;
for(i=; i<K; i++)
{
int len = G[i].size();
int x=G[i][], y;
for(j=; j<len; j++)
{
y = G[i][j];
dp[i|Line[x][y]] = min(dp[i|Line[x][y]], dp[i]+);
}
} printf("Case %d: %d\n", iCase++, dp[K]);
}
return ;
} /** 2 3
0 0
1 1
2 2 3
0 0
1 1
2 3 */
 

(状压) Brush (IV) (Light OJ 1018)的更多相关文章

  1. Light OJ 1018 - Brush (IV)

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

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

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

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

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

  4. Light OJ 1011 - Marriage Ceremonies(状压DP)

    题目大意: 有N个男人,和N个女人要互相匹配,每个男人和每个女人有个匹配值. 并且匹配只能是1对1的. 问所有人都匹配完成,最大的匹配值是多少?   状压DP,暴力枚举就OK了, 这个题目略坑,因为他 ...

  5. 江南OJ 1151 - 还是晒太阳 - [状压DP]

    题目链接:校内OJ的题目,就不放链接了. PS.可以说是本次9月月赛唯一的一道有一定难度的题目了. 题解: 考虑状压DP,假设 $sta$ 是一个二进制数,代表当前 $n$ 个人有几个是在队伍里的,剩 ...

  6. Lightoj 1018 - Brush (IV)

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

  7. 1018 - Brush (IV)

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

  8. [NOIP2016]愤怒的小鸟 D2 T3 状压DP

    [NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...

  9. 【BZOJ2073】[POI2004]PRZ 状压DP

    [BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...

随机推荐

  1. 项目名 的在JSP或JAVA中的另类写法

    在JSP页面中${pageContext.request.contextPath } 表示项目名<form action="${pageContext.request.contextP ...

  2. 8. js中json格式解析

    var doc = O_PARAMETER.FJSonStr;(doc为:{"items":[],"nextId":0}) //1.先转为json对象,主要有以 ...

  3. 【转载】大数据量传输时配置WCF的注意事项

    WCF传输数据量的能力受到许多因素的制约,如果程序中出现因需要传输的数据量较大而导致调用WCF服务失败的问题,应注意以下配置: 1.MaxReceivedMessageSize:获取或设置配置了此绑定 ...

  4. COleChangeSourceDialog不能Change Source的解决方法

      在微软给的例子OClient中,有选中一个OLE对象然后Change Source的功能,但是会报错.分析了一下是这样的: void CMainView::OnOleChangeSource() ...

  5. Web前端之CSS_day1-2

    1.div和span div的语义是division“分割”: span的语义就是span“范围.跨度” div标签是一个容器级标签,里面什么都能放,甚至可以放div自己 span是一个“文本级”的标 ...

  6. 编程范式 episode3 and 4,5

    episode 3 --storage structure. ampersand operate with asterisk --library function episode 4 --generi ...

  7. MySql中的tinying,smallint,int,bigint的类型介绍——转载

    tinyint 从 0 到 255 的整型数据.存储大小为 1 字节. smallint 从 -2^15 (-32,768) 到 2^15 – 1 (32,767) 的整型数据.存储大小为 2 个字节 ...

  8. 深入理解js——执行上下文

    什么是"执行上下文"?暂且不下定义,先看一段代码: 第一句报错,a未定义,很正常.第二句.第三句输出都是undefined,说明浏览器在执行console.log(a)时,已经知道 ...

  9. Android_helloworld

    看见 HelloWorld 相信你就明白我要干什么了.这是每个程序的第一步,让 HelloWorld 带我们走入 Android 的学习之旅吧. 前面我们下载了海马模拟器,所以接下来我们是在模拟器上进 ...

  10. NXP开源自动驾驶计算平台Bluebox 打造现实无人汽车

    知名半导体制造商恩智浦NXP已经准备好了自家的自动驾驶计算开源平台Bluebox,将为汽车制造商提供现成的一体化自动 驾驶计算解决方案.专为自动驾驶设备的BlueBox中央计算引擎.不仅能够为无人驾驶 ...