题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4197

首先,两个人选的数都互质可以看作是一个人选了一个数,就相当于选了一个质因数集合,另一个人不能再选;

想把质因数状压起来,但是数量太多;

有个性质是一个数 x 最多有一个大于根号 x 的质因数,把那个拿出来单独考虑的话,剩下的质因数(小于根号500的)只有8个,可以状压;

于是先对2到 n 的每个数处理出单独的质因数和剩下的质因数状态,然后对单独质因数相同的几个数一起进行DP;

单独质因数相同,那么这几个数要么都被第一个人选,要么都被第二个人选,要么不被选;

所以用一个辅助数组 g 承接之前的 f 值,然后分成 g[0] 和 g[1] 分别表示第一个人选还是第二个人选,0和1之间不互相转移;

最后再把 f 赋回来,要注意这整个集合不被选的状态被算了两次,所以再减掉一个原来的值;

感觉自己好难想出来啊,尤其是那个辅助的 g 数组,但想好了却这么简洁。

代码如下:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. int const maxn=,mx=(<<);
  8. int n,p,pri[]={,,,,,,,};
  9. ll f[mx][mx],g[][mx][mx],ans;
  10. struct N{int s,num;}a[maxn];
  11. bool cmp(N x,N y){return x.num<y.num;}
  12. void init()
  13. {
  14. for(int i=;i<=n;i++)
  15. {
  16. int x=i;
  17. for(int j=;j<;j++)
  18. {
  19. if(x%pri[j])continue;
  20. a[i].s|=(<<j);
  21. while(x%pri[j]==)x/=pri[j];
  22. }
  23. a[i].num=x;
  24. }
  25. }
  26. int main()
  27. {
  28. scanf("%lld%lld",&n,&p);
  29. init();
  30. sort(a+,a+n+,cmp);//a+2
  31. f[][]=;
  32. for(int i=;i<=n;i++)
  33. {
  34. if(i==||a[i].num!=a[i-].num||a[i].num==)//1表示没有大于根号n的质因子,所以每次重新DP
  35. memcpy(g[],f,sizeof f),memcpy(g[],f,sizeof f);
  36. for(int j=mx-;j>=;j--)
  37. for(int k=mx-;k>=;k--)//倒序
  38. {
  39. if(j&k)continue;
  40. if(!(a[i].s&k)) (g[][j|a[i].s][k]+=g[][j][k])%=p;
  41. if(!(a[i].s&j)) (g[][j][k|a[i].s]+=g[][j][k])%=p;
  42. }
  43. if(i==n||a[i].num!=a[i+].num||a[i].num==)
  44. {
  45. for(int j=mx-;j>=;j--)
  46. for(int k=mx-;k>=;k--)
  47. // if(!(j&k)) (f[j][k]+=g[0][j][k]+g[1][j][k]-f[j][k])%=p;//已把之前f的值赋给g
  48. if(!(j&k)) (f[j][k]=(g[][j][k]+g[][j][k]-f[j][k])%p+p)%p;//+p%p
  49. }
  50. }
  51. for(int j=mx-;j>=;j--)
  52. for(int k=mx-;k>=;k--)
  53. if(!(j&k)) (ans+=f[j][k])%=p;
  54. printf("%lld\n",ans);
  55. return ;
  56. }

bzoj4197 [Noi2015]寿司晚宴——状压DP的更多相关文章

  1. 【BZOJ4197】[Noi2015]寿司晚宴 状压DP+分解质因数

    [BZOJ4197][Noi2015]寿司晚宴 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴 ...

  2. 【BZOJ-4197】寿司晚宴 状压DP

    4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 694  Solved: 440[Submit][Status] ...

  3. [NOI2015]寿司晚宴 --- 状压DP

    [NOI2015]寿司晚宴 题目描述 为了庆祝NOI的成功开幕,主办方为大家准备了一场寿司晚宴. 小G和小W作为参加NOI的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了n−1种不同的寿 ...

  4. B4197 [Noi2015]寿司晚宴 状压dp

    这个题一开始想到了唯一分解定理,然后状压.但是显然数组开不下,后来想到每个数(n<500)大于19的素因子只可能有一个,所以直接单独存就行了. 然后正常状压dp就很好搞了. 题干: Descri ...

  5. BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解

    挺神的一道题 ~ 由于两个人选的数字不能有互质的情况,所以说对于一个质因子来说,如果 1 选了,则 2 不能选任何整除该质因子的数. 然后,我们发现对于 1 ~ 500 的数字来说,只可能有一个大于 ...

  6. [NOI2015]寿司晚宴——状压dp

    题目转化:将2~n的数分成两组,可以不选,使得这两组没有公共的质因子.求方案数. 选择了一个数,相当于选择了它的所有质因子. 30分: 发现,n<=30的时候,涉及到的质因子也就10个.2,3, ...

  7. BZOJ 4197 NOI 2015 寿司晚宴 状压DP

    4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 694  Solved: 440[Submit][Status] ...

  8. NOI 2015 寿司晚宴 (状压DP+分组背包)

    题目大意:两个人从2~n中随意取几个数(不取也算作一种方案),被一个人取过的数不能被另一个人再取.两个人合法的取法是,其中一个人取的任何数必须与另一个人取的每一个数都互质,求所有合法的方案数 (数据范 ...

  9. [NOI2015][bzoj4197] 寿司晚宴 [状压dp+质因数]

    题面 传送门 思路 首先,要让两个人选的数字全部互质,那么有一个显然的充要条件:甲选的数字的质因数集合和乙选的数字的质因数集合没有交集 30pt 这种情况下n<=30,也就是说可用的质数只有10 ...

随机推荐

  1. JS高级——函数的调用模式

    函数调用模式一共有四种 <script> //1.函数模式 //this指向window全局对象 //2.方法模式 //this指向调用这个方法的对象 //3.构造函数模式 //this ...

  2. Eclipse + Pydev开发Python时import报错解决方法

    一.  原文链接:http://blog.csdn.net/lhanchao/article/details/51306626            用eclipse +PyDev开发python时, ...

  3. 文件下载之ServletOutputStream

    使用response.getOutputStream可以获取ServletOutputStream,从而实现向页面发送流数据.但是需要注意的是,不能使用ajax进行请求,因为这样页面不会有任何反应,可 ...

  4. Springboot启动工程后,浏览器出现输入用户名和密码

    在使用spring boot的时候发现启动项目时,浏览器需要输入用户名和密码. baidu后发现是因为pom中引用了Spring Security,但是项目中没有使用,在pom中注释掉即可.

  5. javascript 大数据处理方法

    随着前端的飞速发展,在浏览器端完成复杂的计算,支配并处理大量数据已经屡见不鲜.那么,如何在最小化内存消耗的前提下,高效优雅地完成复杂场景的处理,越来越考验开发者功力,也直接决定了程序的性能. 本文展现 ...

  6. js的hex转base64

    if (!window.atob) { var tableStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456 ...

  7. Java字符字符串类

    Java字符字符串类 Character 类 Character 类用于对单个字符进行操作.Character 类在对象中包装一个基本类型 char 的值在实际开发过程中,我们经常会遇到需要使用对象, ...

  8. iview表单密码自定义验证

    From中定义   ref="passwordForm" 获取dom节点  :model="passwordForm" 关联表单数据对象 :rules=&quo ...

  9. 编译OpenWrt失败

    /home/fly/work_dir/OpenWrt-SDK/OpenWrt-Test/trunk/scripts/download.pl "/home/fly/work_dir/OpenW ...

  10. sencha touch 2制作滑动DataView(无缝list)

    Ext.define('App.view.Sections', { extend: 'Ext.dataview.DataView', xtype: 'sectionslist', id: 'mainl ...