NOIP模拟 乘积 - 状压dp + 分组背包
题目大意:
给出n和k,求从小于等于n的数中取出不超过k个,其乘积是无平方因子数的方案数。无平方因子数:不能被质数的平方整除。
题目分析:
10(枚举\(n\le8\)),40(简单状压\(n\le16\)),70(高级状压\(n\le30\)),100(正解状压n\le500,k\le500)。
对于前百分之70,由于\(n\le30\),质数只有10个,直接状压水。
正解(状压dp+分组背包):
注意到1~n中每个数含有的大于\(\sqrt{n}\)的质因数最多有1种,而\(\sqrt{n}\)内的质数只有8个,于是可以分别对待:
将1~n的数进行分组,含有大于\(\sqrt{n}\)的数分为一组,不含的单独成组,组内的每个元素用8位二进制表示该数含有的小于等于\(\sqrt{n}\)的质因子。
这样分组是因为小于等于\(\sqrt{n}\)的质数只有8个可以方便的进行状压dp,而含有大于\(\sqrt{n}\)质因子(只有1种)的数无法进行状压(时空不够),于是将其放在一个组内,dp时只取出该组中的一个数(保证大于\(\sqrt{n}\)的质因子不平方),从而降低时空。
code:
#include<bits/stdc++.h>
using namespace std;
const int N = 550, Mod = 1e9+7;
int T, n, k, dp[N][(1<<8)+50], state[N], val[N];
const int prime[10] = {2, 3, 5, 7, 11, 13, 17, 19};
vector<int> vec[N];
int main(){
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &k);
for(register int i = 1; i <= n; i++) vec[i].clear(), state[i] = 0;
for(register int i = 1; i <= n; i++){
val[i] = i;
for(register int j = 0; j < 8; j++){
if(val[i] % prime[j] == 0){
val[i] /= prime[j];
if(val[i] % prime[j] == 0){
state[i] = -1; //能够整除质数平方不合法
}
else state[i] |= (1 << j);
}
}
}
for(register int i = 1; i <= n; i++){
if(state[i] == -1) continue;
if(val[i] == 1){
vec[i].push_back(i); //不包含大于sqrtn的质因数
}
else vec[val[i]].push_back(i); //大于等于sqrtn的质因数只可能有一个
}
for(register int i = 1; i <= n; i++)
for(register int j = 0; j < 256; j++)
dp[i][j] = 0;
dp[0][0] = 1;
for(register int i = 1; i <= n; i++){
int vecSze = vec[i].size();
static int tmp[N];
for(register int j = 0; j < vecSze; j++) tmp[j] = state[vec[i][j]]; //卡常操作
for(register int l = k; l >= 1; l--){ //一组之中只能选择一个状态,l倒序
for(register int j = 0; j < vecSze; j++){
for(register int sta = (255^tmp[j]); ; sta = (255^tmp[j]) & (sta - 1)){ //枚举补集,减少一些赘余的状态
dp[l][sta | tmp[j]] = (dp[l][sta | tmp[j]] + dp[l-1][sta]) % Mod;
if(!sta) break;
}
}
}
}
int ans = 0;
for(register int i = 0; i < 256; i++){
for(register int j = 1; j <= k; j++)
ans = (ans + dp[j][i]) % Mod;
}
printf("%d\n", ans);
}
return 0;
}
NOIP模拟 乘积 - 状压dp + 分组背包的更多相关文章
- NOI 2015 寿司晚宴 (状压DP+分组背包)
题目大意:两个人从2~n中随意取几个数(不取也算作一种方案),被一个人取过的数不能被另一个人再取.两个人合法的取法是,其中一个人取的任何数必须与另一个人取的每一个数都互质,求所有合法的方案数 (数据范 ...
- HDU - 6125: Free from square (状压DP+分组背包)
problem:给定N,K.表示你有数1到N,让你最多选择K个数,问有多少种方案,使得选择的数的乘积无平方因子数.N,K<500: solution:显然可以状压DP做,但是500以内的素数还是 ...
- HDU 6125 Free from square (状压DP+分组背包)
题目大意:让你在1~n中选择不多于k个数(n,k<=500),保证它们的乘积不能被平方数整除.求选择的方案数 因为质数的平方在500以内的只有8个,所以我们考虑状压 先找出在n以内所有平方数小于 ...
- 树形DP和状压DP和背包DP
树形DP和状压DP和背包DP 树形\(DP\)和状压\(DP\)虽然在\(NOIp\)中考的不多,但是仍然是一个比较常用的算法,因此学好这两个\(DP\)也是很重要的.而背包\(DP\)虽然以前考的次 ...
- HDU 2923 Relocation(状压dp+01背包)
题目代号:HDU2923 题目链接:http://poj.org/problem?id=2923 Relocation Time Limit: 1000MS Memory Limit: 65536K ...
- [CSP-S模拟测试]:点亮(状压DP+树上背包DP)
题目传送门(内部题121) 输入格式 第一行,一个正整数$n$. 第二行,$n-1$个正整数$p_2,p_3,...,p_n$.保证$p_u$是在$1$到$u-1$中等概率随机选取的. 接下来$n$行 ...
- hdu 6125 状压dp+分组
一道玄学题... 其实一开始想的是对的,优化一下就好了 首先我们会发现,乘积不能被完全平方数整除等价于所有因子的每个质因子个数和都至多为1 可是500以内的质数很多,全找出来会爆炸的 可我们会发现,如 ...
- poj 2923 状压dp+01背包
好牛b的思路 题意:一系列物品,用二辆车运送,求运送完所需的最小次数,两辆车必须一起走 解法为状态压缩DP+背包,本题的解题思路是先枚举选择若干个时的状态,总状态量为1<<n,判断这些状态 ...
- BZOJ 4145: [AMPPZ2014]The Prices( 状压dp + 01背包 )
我自己只能想出O( n*3^m )的做法....肯定会T O( nm*2^m )做法: dp( x, s ) 表示考虑了前 x 个商店, 已买的东西的集合为s. 考虑转移 : 先假设我们到第x个商店去 ...
随机推荐
- node.js服务器核心http和文件读写
使用htpp给客服端的数据,把数据交给浏览器渲染.利用 http创建服务器,如客户端请求为:127.0.0.1:3000或127.0.0.1:3000/xxx.html时 ,判断www文件夹中,文件 ...
- vue权限控制菜单显示的简单实现
为了对于不同角色显示不同的菜单 思路1: 本地放一份完整的菜单数据,通过后台返回角色的菜单列表.两者对比,筛选需要显示的菜单数据绑定, 这里有个问题就是路由vue实例初始化就生成了,加载的全部,人为输 ...
- Day2:模块初识
一.模块(库) 别人写好的一堆功能,封装起来,你直接导入就可以用,就不用自己再写一次,使用import方法 二.分类:标准库与第三方库 标准库:免安装,导入即可使用,最常用的一些功能 第三方库:需要下 ...
- Virtualizing memory type
A processor, capable of operation in a host machine, including memory management logic to support a ...
- PHP回调函数--call_user_func_array
我这是抄的 感谢 https://www.cnblogs.com/zzl-21086595/p/4547519.html 全局函数的回调 这里的全局函数的意思,是直接使用function定义的函数,它 ...
- 11995 - I Can Guess the Data
大意:猜数据结构是栈.队列或者优先队列,可能为两种以上,也可能都不是. 水题.. STL 记得判断是否为空 #include<iostream> #include<cstdio> ...
- JScript使用正则表达式的经验
作者:朱金灿 来源:http://blog.csdn.net/clever101 在JScript使用正则表达式时有不少元字符在试图对其进行匹配时需要进行特殊的处理.要匹配这些特殊字符,必须首先将这些 ...
- css实现悬浮效果的阴影
要实现的效果图: 图片.png 实现的代码: -webkit-box-shadow:0px 3px 3px #c8c8c8 ; -moz-box-shadow:0px 3px 3px #c8c8c8 ...
- Android——WebView方式开发web App
昨天接到个酬劳丰厚的任务.把java新生系统做成webApp,想想蛮简单的.所以当时就装作非常为难的样子答应了. 所谓Web App,用曾经我那个老PM的话来说.就是在壳里面套上页面.这里的壳相当于浏 ...
- [Angular2 Form] Reactive Form, show error message for one field
<form [formGroup]="reactiveForm" novalidate autocomplete="off"> <div cl ...