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个商店去 ...
随机推荐
- css页面滚动条出现时防止页面跳动的方法
大家写页面时应该都遇到过一个问题,尤其是写单页面应用的时候, 在有滚动条页面和没有滚动条页面之间相互跳转时, 你页面的主体内容会向左或者向右抖一下,让强迫症看了很不舒服. 现在就来解救一下强迫症: 方 ...
- Linux高性能server编程——系统检測工具
系统检測工具 tcpdump tcpdump是一款经典的抓包工具,tcpdump给使用者提供了大量的选项,泳衣过滤数据报或者定制输出格式. lsof lsof是一个列出当前系统打开的文件描写叙述符的工 ...
- (转)Windows2008优化IIS7.5支持10万个同时请求的配置方法
通过对IIS7的配置进行优化,调整IIS7应用池的队列长度,请求数限制,TCPIP连接数等方面,从而使WEB服务器的性能得以提升,保证WEB访问的访问流畅. 在运行中cmd后,输入:C:\Window ...
- CSDN日报20170406 ——《代码非常烂,所以离职。》
[程序人生]代码非常烂.所以离职? 作者:stormzhang 我在面试的时候一般会问这么一个问题:你为什么离职? 当中有不少同学会提到这么一个原因.现在的项目代码太烂了,前人留下了非常多坑,我实在忍 ...
- linux 安装完mysql 密码重置
If you have forgot the MySQL root password, can’t remember or want to break in….. you can reset them ...
- 【t086】防护伞
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 据说2012的灾难和太阳黑子的爆发有关.于是地球防卫小队决定制造一个特殊防护伞,挡住太阳黑子爆发的区域 ...
- php压缩
php压缩的一个demo,随便测试了一下,可以用 <?php class PHPZip { private $ctrl_dir = array(); private $datasec = arr ...
- 利用a标签导出csv文件
原文 简书原文:https://www.jianshu.com/p/a8687610cda3 大纲 1.需求分析 2.通过a标签实现文件导出 3.实现方式 1.需求分析 导出文件,使用最多的方式还是服 ...
- 浅谈java中异常抛出后代码是否会继续执行
问题 今天遇到一个问题,在下面的代码中,当抛出运行时异常后,后面的代码还会执行吗,是否需要在异常后面加上return语句呢? public void add(int index, E element) ...
- php thinkphp uploadify
模板文件: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w ...