Prime Switch

题目连接:

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4924

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的更多相关文章

  1. UVaLive 6625 Diagrams & Tableaux (状压DP 或者 DFS暴力)

    题意:给一个的格子图,有 n 行单元格,每行有a[i]个格子,要求往格子中填1~m的数字,要求每个数字大于等于左边的数字,大于上边的数字,问有多少种填充方法. 析:感觉像个DP,但是不会啊...就想暴 ...

  2. UVALive - 6912 Prime Switch (状压DP)

    题目链接:传送门 [题意]有n个灯,m个开关,灯的编号从1~n,每个开关上有一个质数,这个开关同时控制编号为这个质数的倍数的灯,问最多有多少灯打开. [分析]发现小于根号1000的质数有10个左右,然 ...

  3. UVALive 6912 Prime Switch 暴力枚举+贪心

    题目链接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show ...

  4. 状压DP uvalive 6560

    // 状压DP uvalive 6560 // 题意:相邻格子之间可以合并,合并后的格子的值是之前两个格子的乘积,没有合并的为0,求最大价值 // 思路: // dp[i][j]:第i行j状态下的值 ...

  5. UVAlive 6560 - The Urge to Merge(状压dp)

    LA 6560 - The Urge to Merge option=com_onlinejudge&Itemid=8&page=show_problem&problem=45 ...

  6. LGTB与序列 状压dp

    考试一看我就想到了状压dp.当时没有想到素数,以为每一位只有0~9这些数,就开始压了.后来发现是小于30,然后改到了15,发现数据一点不给面子,一个小点得数都没有,完美爆零.. 考虑到bi最多变成58 ...

  7. Codeforces 895C - Square Subsets 状压DP

    题意: 给了n个数,要求有几个子集使子集中元素的和为一个数的平方. 题解: 因为每个数都可以分解为质数的乘积,所有的数都小于70,所以在小于70的数中一共只有19个质数.可以使用状压DP,每一位上0表 ...

  8. 洛谷P2761 软件补丁问题(状压dp)

    传送门 啊咧……这题不是网络流二十四题么……为啥是个状压dp…… 把每一个漏洞看成一个状态,直接硬上状压dp 然后因为有后效型,得用spfa //minamoto #include<iostre ...

  9. HDU-3681-Prison Break(BFS+状压DP+二分)

    Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one da ...

随机推荐

  1. hdu 5385 The path

    http://acm.hdu.edu.cn/showproblem.php?pid=5385 题意: 给定一张n个点m条有向边的图,构造每条边的边权(边权为正整数),令d(x)表示1到x的最短路,使得 ...

  2. Spring RedisTemplate操作-List操作(4)

    @Autowired @Resource(name="redisTemplate") private RedisTemplate<String, String> rt; ...

  3. jQuery中Animate进阶用法(三)

    progressType: Function( Promise animation, Number progress, Number remainingMs )每一步动画完成后调用的一个函数,无论动画 ...

  4. python 多进程的启动和代码执行顺序

    对照着廖雪峰的网站学习Python遇到些问题: 在进程中,父进程创建子进程时发现,显示不是按照顺序显示,疑问? 参照代码如下: from multiprocessing import Pool imp ...

  5. Gitlab的安装汉化及问题解决

    Gitlab的安装汉化及问题解决(2017/12/14目前版本为10.2.4) 一.前言 Gitlab需要安装的包太TM多了,源码安装能愁死个人,一直出错,后来发现几行命令就装的真是遇到的新大陆一样. ...

  6. springboot配置mybatis的mapper路径

    1.在src/main/resources/目录下新建mybatis文件夹,将xxx.xml文件放入该文件夹内 2.在application.yml文件中配置: mybatis: configurat ...

  7. Python_oldboy_自动化运维之路_面向对象(十)

    面向对象编程 OOP编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向 ...

  8. ntpdate时间同步

    为什么需要网络同步时间: Linux服务器运行久时,系统时间就会存在一定的误差,一般情况下可以使用date命令进行时间设置,但在做数据库集群分片等操作时对多台机器的时间差是有要求的,此时就需要使用nt ...

  9. C++ code:动态内存

    C++给我们提供了动态内存分配的new和delete操作.一般而论,new和delete操作多用在内存需求捉摸不定的场合.然而,需要处理的数据,如果变动范围很小,我们可以用STL中通用型的容器来做,大 ...

  10. 数组中累加和小于等于k的最长子数组

    问题描述: 给定一个无序数组arr,其中元素可正.可负.可0,给定一个整数 k.求arr所有的子数组中累加和小于或等于k的最长子数组长度.例如:arr=[3,-2,-4,0,6],k=-2,相加和小于 ...