bzoj 2734 集合悬殊 (状压dp)
2024-08-30 10:15:03
大意: 给定$n$, 求集合{1,2,...n}的子集数, 满足若$x$在子集内, 则$2x,3x$不在子集内.
记$f(x)$为$x$除去所有因子2,3后的数, 那么对于所有$f$值相同的数可以划分为一个等价类, 对2的倍数和3的倍数建一个二维的表, 在表上做状压$dp$即可. 最后答案就为每个等价类方案的乘积.
#include <iostream>
#include <string.h>
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
typedef long long ll;
const int P = 1e9+1; const int N = 1e5+10;
int n, vis[N];
int a[30], s[1<<11];
int dp[2][1<<11]; int calc(int x) {
memset(dp,0,sizeof dp);
memset(a,0,sizeof a);
int dx = 0, dy = 0;
for (int i=1,t=x; t<=n; t*=2,++i) {
for (int j=1,tt=t; tt<=n; tt*=3,++j) {
(a[i]<<=1)|=1, vis[tt] = 1;
dx = max(dx, i);
dy = max(dy, j);
}
}
int mx = (1<<dy)-1, cnt = 0;
REP(i,0,mx) if (!(i&i<<1)) s[++cnt] = i;
int cur = 0;
dp[cur][1] = 1;
REP(i,1,dx) {
cur ^= 1;
memset(dp[cur],0,sizeof dp[cur]);
REP(j,1,cnt) if (dp[!cur][j]) {
REP(k,1,cnt) if (!(s[j]&s[k])&&(s[k]|a[i])==a[i]) {
dp[cur][k]=(dp[cur][k]+dp[!cur][j])%P;
}
}
}
int ans = 0;
REP(i,1,cnt) ans=(ans+dp[cur][i])%P;
return ans;
} int main() {
scanf("%d", &n);
int ans = 1;
REP(i,1,n) if (!vis[i]) ans=(ll)ans*calc(i)%P;
printf("%d\n", ans);
}
最新文章
- 【BZOJ-4289】Tax 最短路 + 技巧建图
- SQL Server常用语句
- Scrapy
- HDU 1851 (巴什博奕 SG定理) A Simple Game
- URAL 1994 The Emperor&#39;s plan 求组合数 大数用log+exp处理
- Mini-project # 1 - Rock-paper-scissors-___An Introduction to Interactive Programming in Python";RICE";
- python基础教程(六)
- javascript 学习笔记 -- js获取本地文件信息
- aerospike数据库配置
- mysql5.7 参数记录 (持续更新)
- 步步为营-84-数字转化为金额的Js+enter键取消页面刷新
- kubernetes控制器之DaemonSet
- [Leetcode 100]判断二叉树相同 Same Tree
- IplImage 与mat之间的转换及释放内存
- Golang 使用FreeType-go进行字体
- 使用Github的高级搜索功能
- 机器学习实战:用nodejs实现人脸识别
- 一个用于发送HTML格式邮件的类
- 强化学习之QLearning
- java多线程-cas及atomic
热门文章
- python 进程池和任务量变化测试
- Mybatis 传入多个参数查询数据 (3种方法)
- 我用asp.net core 部署到docker遇到的问题
- postgresql interval 字段拼接
- nodeJS 项目如何运行
- MongoDB(mongodb-win32-x86_64-enterprise-windows-64-4.2.1-signed.msi)下载,启动和插入数据,查询
- SQL-W3School-高级:SQL UNION 和 UNION ALL 操作符
- Android控件RecyclerView的基本用法
- oracle数据库使用PL/sql导入excel数据
- python3 高级编程(一) 使用__slots__