UVALive 6912 Prime Switch 状压DP
Prime Switch
题目连接:
Description
There are lamps (uniquely numbered from 1 to N) and K switches. Each switch has one prime number
written on it and it is connected to all lamps whose number is a multiple of that prime number. Pressing
a switch will toggle the condition of all lamps which are connected to the pressed switch; if the lamp
is off then it will be on, and vice versa. You can press only one switch at one time; in other words,
no two switches can be pressed together at the same time. If you want to press multiple switches, you
should do it one by one, i.e. allowing the affected lamps of the previous switch toggle their condition
first before pressing another switch.
Initially all the lamps are off. Your task is to determine the maximum number of lamps which can
be turned on by pressing one or more switches.
For example, let there be 10 lamps (1 . . . 10) and 2 switches which numbers are 2 and 5 as shown
in the following figure.
In this example:
• Pressing switch 2 will turn on 5 lamps: 2, 4, 6, 8, and 10.
• Pressing switch 5 will turn on 2 lamps: 5 and 10.
• Pressing switch 2 and 5 will turn on 5 lamps: 2, 4, 5, 6, and 8. Note that lamp number 10 will
be turned off as it is toggled twice, by switch 2 and switch 5 (off → on → off).
Among all possible switches combinations, the maximum number of lamps which can be turned on
in this example is 5.
Input
The first line of input contains an integer T (T ≤ 100) denoting the number of cases. Each case begins
with two integers in a line: N and K (1 ≤ K ≤ N ≤ 1, 000), denoting the number of lamps and
switches respectively. The next line contains K distinct prime numbers, each separated by a single
space, representing the switches number. You are guaranteed that the largest number among those
switches is no larger than N
Output
For each case, output ‘Case #X: Y ’, where X is the case number starts from 1 and Y is the maximum
number of lamps which can be turned on for that particular case.
Explanation for 2nd sample case:
You should press switch 2 and 7, such that 11 lamps will be turned on: 2, 4, 6, 7, 8, 10, 12, 16, 18,
20, and 21. There exist some other combinations which can turn on 11 lamps, but none can turn more
than 11 lamps on.
Explanation for 3rd sample case:
There is only one switch, and pressing it will turn 20 lamps on.
Explanation for 4th sample case:
Pressing all switches will turn 42 lamps on, and it is the maximum possible in this case
Sample Input
4
10 2
2 5
21 4
2 3 5 7
100 1
5
100 3
3 19 7
Sample Output
Case #1: 5
Case #2: 11
Case #3: 20
Case #4: 42
Hint
题意
你有n盏灯,有m个开关,开关上面都写着一个质数
那么这个开关就控制着上面写着的数字的倍数。
灯泡按奇数次就亮着,偶数次,就熄灭。
问你最好情况下,最优有多少个灯亮着。
题解:
对于小于等于31的素数,我们状压去跑dp,对于大于的,我们就贪心。
因为大于31的素数一定是不会冲突的,因为上面的数乘起来就大于1000了。
然后这样就行了。
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 15;
int N,K,pr[maxn],pre[maxn],prime[maxn],primelen,ha[maxn],tot,op[maxn],flag[maxn],temp[maxn];
vector < int > ap;
void Init(){
memset( ha , -1 , sizeof( ha ) );
for(int i = 2 ; i < maxn ; ++ i) if(!pre[i]){
for(int j = i + i ; j < maxn ; j += i) pre[j] = 1;
prime[ primelen ++ ] = i;
}
}
int solve( int bit ){
for(int i = 1 ; i <= N ; ++ i) flag[i] = 0;
for(int i = 0 ; i < tot ; ++ i) if( bit >> i & 1 ){
for(int j = op[i] ; j <= N ; j += op[i] ) flag[j] ^= 1;
}
for(auto it : ap){
int add = 0;
for(int i = it ; i <= N ; i += it) if( flag[i] == 0 ) ++ add ; else -- add;
if( add > 0 ) for(int i = it ; i <= N ; i += it) flag[i] ^= 1;
}
int rs = 0;
for(int i = 1 ; i <= N ; ++ i) rs += flag[i];
return rs;
}
int main(int argc,char *argv[]){
int T,cas=0;
Init();
scanf("%d",&T);
while(T--){
scanf("%d%d",&N,&K);
for(int i = 0 ; i < K ; ++ i) scanf("%d" , pr + i);
sort( pr , pr + K );
tot = 0;ap.clear();
for(int i = 0 ; i < K ; ++ i) if( pr[i] <= 31 ) op[tot ++ ] = pr[i];else ap.push_back( pr[i] );
int mx = 0;
for(int i = 0 ; i < (1 << tot) ; ++ i) mx = max( mx , solve( i ) );
printf("Case #%d: %d\n", ++ cas , mx);
}
return 0;
}
UVALive 6912 Prime Switch 状压DP的更多相关文章
- UVaLive 6625 Diagrams & Tableaux (状压DP 或者 DFS暴力)
题意:给一个的格子图,有 n 行单元格,每行有a[i]个格子,要求往格子中填1~m的数字,要求每个数字大于等于左边的数字,大于上边的数字,问有多少种填充方法. 析:感觉像个DP,但是不会啊...就想暴 ...
- UVALive - 6912 Prime Switch (状压DP)
题目链接:传送门 [题意]有n个灯,m个开关,灯的编号从1~n,每个开关上有一个质数,这个开关同时控制编号为这个质数的倍数的灯,问最多有多少灯打开. [分析]发现小于根号1000的质数有10个左右,然 ...
- UVALive 6912 Prime Switch 暴力枚举+贪心
题目链接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show ...
- 状压DP uvalive 6560
// 状压DP uvalive 6560 // 题意:相邻格子之间可以合并,合并后的格子的值是之前两个格子的乘积,没有合并的为0,求最大价值 // 思路: // dp[i][j]:第i行j状态下的值 ...
- UVAlive 6560 - The Urge to Merge(状压dp)
LA 6560 - The Urge to Merge option=com_onlinejudge&Itemid=8&page=show_problem&problem=45 ...
- LGTB与序列 状压dp
考试一看我就想到了状压dp.当时没有想到素数,以为每一位只有0~9这些数,就开始压了.后来发现是小于30,然后改到了15,发现数据一点不给面子,一个小点得数都没有,完美爆零.. 考虑到bi最多变成58 ...
- Codeforces 895C - Square Subsets 状压DP
题意: 给了n个数,要求有几个子集使子集中元素的和为一个数的平方. 题解: 因为每个数都可以分解为质数的乘积,所有的数都小于70,所以在小于70的数中一共只有19个质数.可以使用状压DP,每一位上0表 ...
- 洛谷P2761 软件补丁问题(状压dp)
传送门 啊咧……这题不是网络流二十四题么……为啥是个状压dp…… 把每一个漏洞看成一个状态,直接硬上状压dp 然后因为有后效型,得用spfa //minamoto #include<iostre ...
- HDU-3681-Prison Break(BFS+状压DP+二分)
Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...
随机推荐
- 浅谈fhq treap
一.简介 fhq treap 与一般的treap主要有3点不同 1.不用旋转 2.以merge和split为核心操作,通过它们的组合实现平衡树的所有操作 3.可以可持久化 二.核心操作 代码中val表 ...
- 高并发数据库之MySql性能优化实战总结
向MySQL发送一个请求时MySQL具体的操作过程 慢查询 1.慢查询 SHOW VARIABLES LIKE '%quer%' 索引优化技巧 1.对于创建的多列索引(复合)索引,只要查询条件使用了最 ...
- MYSQL查询重复记录的方法
select * from hengtu_demandpush a where (a.did,a.mid) in (select did,mid from hengtu_demandpush grou ...
- argunlar 1.0.1 【数据绑定】
<!DOCTYPE html><html lang="en" ng-app><head> <meta charset="U ...
- 【转】VTL-vm模板的变量用法
http://www.cnblogs.com/zengxlf/archive/2009/05/06/1451004.html 加载foot模块页 #parse("foot.vm") ...
- 存储之磁盘阵列RAID
存储之磁盘阵列RAID RAID是由美国加州大学伯克利分校的D.A. Patterson教授在1988年提出的.RAID名为独立冗余磁盘阵列(RedundantArray of Indepe ...
- Regular Expression Matching & Wildcard Matching
Regular Expression Matching Implement regular expression matching with support for '.' and '*'. '.' ...
- Shell-遍历删除指定目录
Code: find $LibPath/ -name .svn | xargs rm -rf
- Linux6.5 安装Python3.X(转载)
1.获取Python 3.6.3 通过官网https://www.python.org/downloads/下载Python 3.4.3源码: 源码获取命令如下:wget https://www.py ...
- jenkins 使用Git持续构建
为jenkins添加git插件. 在Available tab页中找到Git Plugin 点击下方的Install without Restart安装插件. 插件安装完毕后,我们需要在jenkins ...