(状压) Brush (IV) (Light OJ 1018)
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 |
- #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)的更多相关文章
- Light OJ 1018 - Brush (IV)
题目大意: 一个二维平面上有N个点,一把刷子,刷一次可以把一条线上的所有点都刷掉.问最少刷多少次,可以把全部的点都刷完 状态压缩DP, 用记忆化搜索来写, 需要有个优化不然会超时. ===== ...
- Light oj 1018 - Brush (IV) 状态压缩
题目大意: 给出n个点的坐标,求至少画多少掉直线才能连接所有点. 题目思路:状态压缩 首先经行预处理,求出所有状态下,那些点不在该状态内 以任意两点为端点求出这条直线的状态 枚举所有状态,找出不在当前 ...
- LightOJ1018 Brush (IV)(状压DP)
题目大概说一个平面有n个灰尘,可以用一把刷子直直刷过去清理直线上的所有灰尘,问最少要刷几下才能清理完所有灰尘. 首先怎么刷其实是可以确定的,或者说直线有哪些是可以确定的,而最多就有C(n,2)条不一样 ...
- Light OJ 1011 - Marriage Ceremonies(状压DP)
题目大意: 有N个男人,和N个女人要互相匹配,每个男人和每个女人有个匹配值. 并且匹配只能是1对1的. 问所有人都匹配完成,最大的匹配值是多少? 状压DP,暴力枚举就OK了, 这个题目略坑,因为他 ...
- 江南OJ 1151 - 还是晒太阳 - [状压DP]
题目链接:校内OJ的题目,就不放链接了. PS.可以说是本次9月月赛唯一的一道有一定难度的题目了. 题解: 考虑状压DP,假设 $sta$ 是一个二进制数,代表当前 $n$ 个人有几个是在队伍里的,剩 ...
- 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 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
随机推荐
- I2C控制器的Verilog建模之一
前言:之前申请了ADI公司的一款ADV7181CBSTZ的视频解码芯片,正好原装DE2板子安的是同系列的ADV7181BBSTZ.虽然都是ADV7181的宗出,但是寄存器配置等等还是有些诧异,引脚也不 ...
- 关于对inputstream流的复制
今天因为项目需要,获取到一个inputstream后,可能要多次利用它进行read的操作.由于流读过一次就不能再读了,所以得想点办法. 而InputStream对象本身不能复制,因为它没有实现Clon ...
- jquery常用正则表达式
1.邮箱验证正则表达式:/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/ 2.手机验证正则表达式:/^ ...
- sql日期函数操作
sql语句获取本周.本月.本年数据 SQL Serverselect * from [data] where DATEPART(m,[date])=2 Accessselect * from [da ...
- JavaWeb项目连接Oracle数据库
参考网址:http://jingyan.baidu.com/article/0320e2c1d4dd0b1b87507b38.html 既然你要链接oracle数据库 ,那么首先就是先打开我们的ora ...
- delegate事件绑定
为了代码的健壮性,绑定事件之前先解绑再进行绑定. var _$div = $("#id");_$div.undelegate("click mouseover mouse ...
- socket笔记
参考: http://www.cnblogs.com/dolphinX/p/3460545.html http://www.cnblogs.com/wei2yi/archive/2011/03/23/ ...
- VC++ CButton::SetCheck 的使用方法
CButton::SetCheck void SetCheck(int nCheck); 参数 nCheck 指定检查状态. 此参数可以是下列值之一: 值 ...
- 面向服务体系架构(SOA)和数据仓库(DW)的思考基于 IBM 产品体系搭建基于 SOA 和 DW 的企业基础架构平台
面向服务体系架构(SOA)和数据仓库(DW)的思考 基于 IBM 产品体系搭建基于 SOA 和 DW 的企业基础架构平台 当前业界对面向服务体系架构(SOA)和数据仓库(Data Warehouse, ...
- 基于CCS3.3平台搭建DSP/BIOS系统
本人由于换工作的原因,由ccs3.1平台下转化为ccs3.3平台.先说说本人感觉的区别,ccs3.1下的CSL库集成到DSP/BIOS内,而3.3的CSL库在DSP/BIOS下就没有体现. 1.二话不 ...