【BZOJ5299】【CQOI2018】解锁屏幕(动态规划,状态压缩)
【BZOJ5299】【CQOI2018】解锁屏幕(动态规划,状态压缩)
题面
Description
使用过Android手机的同学一定对手势解锁屏幕不陌生。Android的解锁屏幕由3x3个点组成,手指在屏幕上画一条
线将其中一些点连接起来,即可构成一个解锁图案。如下面三个例子所示:

画线时还需要遵循一些规则
1.连接的点数不能少于4个。也就是说只连接两个点或者三个点会提示错误。
2.两个点之间的连线不能弯曲。
3.每个点只能"使用"一次,不可重复。这里的"使用"是指手指划过一个点,该点变绿。
4.两个点之间的连线不能"跨过"另一个点,除非那个点之前已经被"使用"过了。
对于最后一条规则,参见下图的解释。左边两幅图违反了该规则:而右边两幅图(分别为2→4→1→3→6和→5→4→1→9→2)
则没有违反规则,因为在"跨过"点时,点已经被"使用"过了。

现在工程师希望改进解锁屏幕,增减点的数目,并移动点的位置,不再是一个九宫格形状,但保持上述画线的规则不变。
请计算新的解锁屏幕上,一共有多少满足规则的画线方案。
Input
输入文件第一行,为一个整数n,表示点的数目。
接下来n行,每行两个空格分开的整数xi和yi,表示每个点的坐标。
-1000≤xi,Yi≤l000,1≤n<20。各点坐标不相同
Output
输出文件共一行,为题目所求方案数除以100000007的余数。
Sample Input
4
0 0
1 1
2 2
3 3
Sample Output
8
解释:设4个点编号为1到4,方案有1→2→3→4,2→1→3→4,3→2→1→4,2→3→1→4,
及其镜像4→3→2→1,3→4→2→1,2→3→4→1,3→2→4→1.
题解
状压\(dp\),坑的死
首先好好观察一下模数,它TM不是\(10^9+7\)
。。。
然后考虑状压
设\(f[i][j]\)表示当前状态是\(i\),当前位置结尾的点是\(j\)的方案数
暴力枚举一下个连接谁,检查它们中间的点是否都已经被选择
如果每次都\(check\)一下,复杂度就会变成\(O(2^nn^3)\)
提前预处理出任意两个点之间的集合,这一步的复杂度是\(O(n^3)\)
计算是否贡献的时候,不要计算出斜率再计算,这样会掉精度
把斜率乘到两边就行了。
然后做\(dp\)的时候就可以\(O(1)\)检查了
这样复杂度就是\(O(n^3+2^nn^2)\),并且不满。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MOD 100000007
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int n,X[20],Y[20];
int g[20][20];
int f[20][1<<20];
void update(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
int main()
{
n=read();
for(int i=0;i<n;++i)X[i]=read(),Y[i]=read();
for(RG int i=0;i<n;++i)
for(RG int j=0;j<n;++j)
{
if(i==j)continue;
for(RG int k=0;k<n;++k)
{
if(k==i||k==j)continue;
if(X[k]<X[i]&&X[k]<X[j])continue;
if(X[k]>X[i]&&X[k]>X[j])continue;
if(Y[k]<Y[i]&&Y[k]<Y[j])continue;
if(Y[k]>Y[i]&&Y[k]>Y[j])continue;
if(Y[i]==Y[k])
{
if(Y[j]==Y[k])g[i][j]|=(1<<k);
continue;
}
if(Y[j]==Y[k])continue;
if((X[i]-X[k])*(Y[j]-Y[k])==(X[j]-X[k])*(Y[i]-Y[k]))g[i][j]|=(1<<k);
}
}
for(RG int i=0;i<n;++i)f[i][1<<i]=1;
for(RG int t=0;t<(1<<n);++t)
for(RG int i=0;i<n;++i)
{
if(!(t&(1<<i)))continue;
if(!f[i][t])continue;
for(RG int j=0;j<n;++j)
{
if(t&(1<<j))continue;
if((g[i][j]&t)!=g[i][j])continue;
update(f[j][t|(1<<j)],f[i][t]);
}
}
int ans=0;
for(RG int t=0;t<(1<<n);++t)
{
int tot=0;
for(RG int i=t;i;i-=i&(-i))++tot;
if(tot<4)continue;
for(RG int i=0;i<n;++i)
if(t&(1<<i))update(ans,f[i][t]);
}
printf("%d\n",ans);
return 0;
}
【BZOJ5299】【CQOI2018】解锁屏幕(动态规划,状态压缩)的更多相关文章
- bzoj5299: [Cqoi2018]解锁屏幕
题目链接 bzoj 5299: [Cqoi2018]解锁屏幕 题解 很水的装压dp,相信没人需要看题解.... dp[i][j]表示状态为i最后一个到的点为j,然后转移就很好写了 不过 我读入优化没读 ...
- BZOJ5299:[CQOI2018]解锁屏幕(状压DP)
Description 使用过Android手机的同学一定对手势解锁屏幕不陌生.Android的解锁屏幕由3x3个点组成,手指在屏幕上画一条 线将其中一些点连接起来,即可构成一个解锁图案.如下面三个例 ...
- BZOJ5299 [Cqoi2018]解锁屏幕 【状压dp】
题目链接 BZOJ5299 题解 就一个毒瘤卡常题..写了那么久 设\(f[i][s]\)表示选了集合\(s\)中的点,最后一个是\(i\),进行转移 要先预处理出两点间的点,然后卡卡常就可以过了 # ...
- [Luogu] P4460 [CQOI2018]解锁屏幕
题目背景 使用过Android 手机的同学一定对手势解锁屏幕不陌生.Android 的解锁屏幕由3X3 个点组成,手指在屏幕上画一条线,将其中一些点连接起来,即可构成一个解锁图案.如下面三个例子所示: ...
- P4460 [CQOI2018]解锁屏幕
算是我比较擅长的类型,自己想想就会了.普通小状压,状态傻子都能想出来.一开始裸的枚举T了,30.后来与处理之后跑的飞起,就是不对,还是30分.后来看讨论版...mod竟然是1e8+7!!!这不有毒吗. ...
- [动态规划]状态压缩DP小结
1.小技巧 枚举集合S的子集:for(int i = S; i > 0; i=(i-1)&S) 枚举包含S的集合:for(int i = S; i < (1<<n); ...
- [POJ 2923] Relocation (动态规划 状态压缩)
题目链接:http://poj.org/problem?id=2923 题目的大概意思是,有两辆车a和b,a车的最大承重为A,b车的最大承重为B.有n个家具需要从一个地方搬运到另一个地方,两辆车同时开 ...
- POJ 1185 炮兵阵地(动态规划+状态压缩)
炮兵阵地 Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原( ...
- ACM学习历程—HDU1584 蜘蛛牌(动态规划 && 状态压缩 || 区间DP)
Description 蜘蛛牌是windows xp操作系统自带的一款纸牌游戏,游戏规则是这样的:只能将牌拖到比她大一的牌上面(A最小,K最大),如果拖动的牌上有按顺序排好的牌时,那么这些牌也跟着一起 ...
- HDOJ-1074(动态规划+状态压缩)
Doing Homework HDOJ-1074 1.本题主要用的是状态压缩的方法,将每种状态用二进制压缩表示 2.状态转移方程:dp[i|(1<<j)]=min(dp[i|(1<& ...
随机推荐
- 基于IDEA的JavaWeb开发环境搭建
基于IDEA的JavaWeb开发环境搭建 基于IDEA的JavaWeb开发环境搭建 jdk下载安装配置环境变量 下载 安装 配置环境变量 下载安装激活使用IntelliJ IDEA 下载 安装 激活 ...
- EOJ-3300 奇数统计(高维前缀和)
题目链接: https://acm.ecnu.edu.cn/problem/3300/ 题目大意: 给n个数,求在n个数中选两个数(可重复),使得这两个数的组合数是奇数,求总共有多少种取法. 解题思路 ...
- 智能机器人“小昆”的实现(五)MainActivty的实现及项目结束
好了,一切准备工作都完成了,下面我们就可以真正的编写MainActivity了.在MainActivity中,我们要为ListView设定适配器,并为发送按钮设定点击事件.我们的逻辑就是点击发送按钮, ...
- Django 模型中FileField字段
FileField¶ class FileField([upload_to=None, max_length=100, **options])¶ 一个上传文件的字段. 注意 FileField字段不支 ...
- Could not publish to the server. null argument:
启动tomcat或clean tomcat报错:Could not publish to the server. null argument: Could not publish to the ser ...
- html5与html的区别
最近看群里聊天聊得最火热的莫过于手机网站和html5这两个词.可能有人会问,这两者有什么关系呢?随着这移动互联网快速发展的时代,尤其是4G时代已经来临的时刻,加上微软对“XP系统”不提供更新补丁.维护 ...
- 大数据-图表插件-echarts 样式修改(迭代)
修改折线图大小 myChart.setOption({ title:{ text:"价格指数" ...
- Visual Studio Installer打包安装项目VS2015
使用VS2015的Visual Studio Installer打包安装项目,虽然整体操作很简单,但还是有几个特殊的点需要记一下,故写下此博客方便以后查阅 第一步,创建安装项目 如下: 里面最左侧的框 ...
- Truncated class file 问题的解决
替换class 文件之后出现了 Truncated class file 问题,查找原因,可能是文件损坏,清理缓存可以解决 解决办法: 把tomcat的work目录直接删掉,让他重新启动.rm -r ...
- 去掉CodeIgniter URL中的index.php
CI默认的rewrite url中是类似这样的,例如你的CI根目录是在/CodeIgniter/下,你的下面的二级url就类似这样http://localhost /CodeIgniter/index ...