[HNOI2012]集合选数(构造,状态压缩,DP)
神仙题。
莫名其妙的就试一试把所有数放进一个类似矩阵的东西里面。
首先把 \(1\) 放到左上角,然后在每个数的右边放它的 \(3\) 倍(大于 \(n\) 就不用放了),下面放它的 \(2\) 倍(大于 \(n\) 就不用放了)。
注意这样子有些数会不在里面。那么从小到大,每次选最小的且没有出现过的数作为一个新的“矩阵”的左上角。容易发现这些“矩阵”互不干扰,对每个矩阵分别求方案数,乘起来就好了。
对于一个矩阵,发现就是对于一个数,如果它选了,那么它右边和下面的都不能选。
问题就变成选一些数,互不相邻的方案数。
由于这个矩阵不会太大(长和宽都是 \(\log\) 级别的),所以直接状压。
时间复杂度,大力分析一波(我的分析特别松,首先假设所有矩阵都是满的,也就是右下角不会空出一块,然后状压时也不考虑能不能删掉无用状态),会得到一个极其松的上界 \(3\times 10^7\)。状压 DP 时剪掉无用状态,就能跑得飞快了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
const int maxn=100010,mod=1000000001;
#define MP make_pair
#define PB push_back
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
inline ll read(){
char ch=getchar();ll x=0,f=0;
while(ch<'0' || ch>'9') f|=ch=='-',ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
int n,ans=1,len[18],f[18][2048],ok[2048],ol;
bool vis[maxn];
bool check(int x){
FOR(i,0,11) if((x>>i)&(x>>(i+1))&1) return false;
return true;
}
int solve(int x){
int y=x,w,s=0;
FOR(i,1,n){
if(y>n) break;
int z=y;
FOR(j,1,n){
if(z>n) break;
len[i]=j;
vis[z]=true;
z*=3;
}
w=i;
y*=2;
}
FOR(i,1,ol){
if(ok[i]>=(1<<len[1])) break;
f[1][i]=1;
if(w==1) s=(s+1)%mod;
}
FOR(i,2,w) FOR(j,1,ol){
if(ok[j]>=(1<<len[i])) break;
f[i][j]=0;
FOR(k,1,ol){
if(ok[k]>=(1<<len[i-1])) break;
if(!(ok[j]&ok[k])) f[i][j]=(f[i][j]+f[i-1][k])%mod;
}
if(i==w) s=(s+f[i][j])%mod;
}
return s;
}
int main(){
n=read();
FOR(i,0,2047) if(check(i)) ok[++ol]=i;
FOR(i,1,n) if(!vis[i]) ans=1ll*ans*solve(i)%mod;
printf("%d\n",ans);
}
[HNOI2012]集合选数(构造,状态压缩,DP)的更多相关文章
- [BZOJ2734][HNOI2012] 集合选数(状态压缩+思维)
Description 题目链接 Solution 可以根据条件构造出一个矩阵, 1 3 9 27 81... 2 6 18.... 4 12 36... 这个矩阵满足\(G[i][1]=G[i-1] ...
- 【BZOJ2734】【HNOI2012】集合选数(状态压缩,动态规划)
[BZOJ2734][HNOI2012]集合选数(状态压缩,动态规划) 题面 Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所 ...
- BZOJ 2734 洛谷 3226 [HNOI2012]集合选数【状压DP】【思维题】
[题解] 思维题,看了别人的博客才会写. 写出这样的矩阵: 1,3,9,... 2,6,18,... 4,12.36,... 8,24,72,... 我们要做的就是从矩阵中选出一些数字,但是不能选相邻 ...
- [HNOI2012]集合选数(状压DP+构造)
题目要求若出现x,则不能出现2x,3x 所以我们考虑构造一个矩阵 \(1\ 2\ 4 \ 8--\) \(3\ 6\ 12\ 24--\) \(9\ 18\ 36--\) \(--\) 不难发现,对于 ...
- BZOJ3724 [HNOI2012]集合选数 【状压dp】
题目链接 BZOJ3724 题解 构造矩阵的思路真的没想到 选\(x\)就不能选\(2x\)和\(3x\),会发现实际可以转化为矩阵相邻两项 \[\begin{matrix}1 & 3 &am ...
- BZOJ2734 HNOI2012集合选数(状压dp)
完全想不到的第一步是构造一个矩阵,使得每行构成公比为3的等比数列,每列构成公比为2的等比数列.显然矩阵左上角的数决定了这个矩阵,只要其取遍所有既不被2也不被3整除的数那么所得矩阵的并就是所有的数了,并 ...
- bzoj2734:[HNOI2012]集合选数(状压DP)
菜菜的喵喵题~ 化序列为矩阵!化腐朽为神奇!左上角为1,往右每次*3,往下每次*2,这样子就把问题转化成了在矩阵里选不相邻的数有几种可能. 举个矩阵的例子 1 3 9 27 2 6 18 54 4 1 ...
- BZOJ_2734_[HNOI2012]集合选数_构造+状压DP
BZOJ_2734_[HNOI2012]集合选数_构造+状压DP 题意:<集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x ...
- bzoj 2734: [HNOI2012]集合选数 状压DP
2734: [HNOI2012]集合选数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 560 Solved: 321[Submit][Status ...
- [HNOI2012]集合选数 --- 状压DP
[HNOI2012]集合选数 题目描述 <集合论与图论>这门课程有一道作业题,要求同学们求出\({1,2,3,4,5}\)的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x ...
随机推荐
- oracle中如何更改一个表的一个字段属性(名称,类型)
修改字段的属性,名称方法 --修改某一个字段的类型,当该字段不为null时alter table 表名add 字段NUMBER(11,0) default 0 not null;--添加表一个字段 A ...
- Docker系列之学习笔记
一.Docker简介 1.1.Docker架构 Docker 使用客户端-服务器 (C/S) 架构模式,分为Docker守护进程和客户端,Docker 客户端,实际上是 docker 的二进制程序,D ...
- 明解JAVA 第二章答案
练习2-1 编译错误,无法运行. 练习2-2 package candle1220; class Nightwatch{ public static void main(String[] args) ...
- Windows重要的win键
win+↓ 当前窗口操作,多按几下就缩没了(同理,其他箭头也一样) win+e 打开此电脑 win+v 展开剪切板 win+k 访问蓝牙 win+a win10的通知 win+d (切到桌面,再用能切 ...
- Java基础扫盲系列(三)— Java内省技术
前言 Java内省技术属于Java基础体系的的一部分,但是很多人都不甚了解.笔者也是在学习Spring源码的过程中遇到该技术模块的.为了完善技术体系,本文将全面的学习该技术.在提到Java内省技术,就 ...
- python语法01
在某.py文件中调用其他.py文件中的内容. 全局变量的使用. 线程的使用. if name == 'main': 的作用 新建两个python脚本文件 f1File.py ""& ...
- netCore3.0+webapi到前端vue(后端)
第一步创建api项目 创建完成启动F5!! 如图 数据库我用的是mysql 用ef操作数据 开发环境:Win10 + VS2019Mysql服务器版本:8.0.16 1.下载并安装插件(必备) MyS ...
- 解决FastCGI 进程超过了配置的活动超时时限的问题
近日,需要满足测试需求,进行大数据并发测试时,报出[HTTP 错误 500.0 - Internal Server Error E:\PHP\php-cgi.exe - FastCGI 进程超过了配置 ...
- vue中输入框只能输入数字
方案1:增加自定义指令 自定义指令写法: directives: { numberOnly: { bind(el) { ...
- matlab 基础语法
计算次幂 Trial>> 3 ^ 2 % 3 raised to the power of 2 ans = 9 MATLAB 计算正弦值 Trial>> sin(pi /2) ...