【bzoj4197】[Noi2015]寿司晚宴 状压DP
来源:互联网 发布:qt淘宝刷单平台哪个好 编辑:程序博客网 时间:2024/04/29 03:46
Description
为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴。小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴。
在晚宴上,主办方为大家提供了 n−1 种不同的寿司,编号 1,2,3,…,n−1,其中第 i 种寿司的美味度为 i+1 (即寿司的美味度为从 2 到 n)。
现在小 G 和小 W 希望每人选一些寿司种类来品尝,他们规定一种品尝方案为不和谐的当且仅当:小 G 品尝的寿司种类中存在一种美味度为 x 的寿司,小 W 品尝的寿司中存在一种美味度为 y 的寿司,而 x 与 y 不互质。
现在小 G 和小 W 希望统计一共有多少种和谐的品尝寿司的方案(对给定的正整数 p 取模)。注意一个人可以不吃任何寿司。
Input
输入文件的第 1 行包含 2 个正整数 n,p,中间用单个空格隔开,表示共有 n 种寿司,最终和谐的方案数要对 p 取模。
Output
输出一行包含 1 个整数,表示所求的方案模 p 的结果。
Sample Input
3 10000
Sample Output
9
HINT
2≤n≤500
0< p≤1000000000
Source
题意:求满足以下条件的集合对(A,B)的数量:
(1) A⊆[2,n], B ⊆[2,n] (2) A∩B=∅ (3) ∀x∈A, y∈B, gcd(x,y)=1
首先看30分。
2~30的质数至多有10个,而两个集合不能选相同的质数,所以可以状压一下:
dp[i][x][y]表示选到第i个数,第一个人选的素数状态是x,第二个人选的素数状态是y的方案数,每次像01背包来转移就能优化掉第一维,然后ans累加就行了。
然后再看100分:
小于
把大质数相同的数放到一个集合里(排一下序),用dp[x][y][0/1]表示第一个人状态是x,第二个人状态是y,大质数分给第一个人/第二个人的方案数。然后状压那里还是像30分算法那样转移状态,唯一的区别就是加个第三维…
然后每次当前大质数的集合开始时,把f复制一份给dp数组让他转移。
结束时,
这是30分:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int SZ = 5010;const int MAXC = (1 << 11) - 1;int pri[233] = {0,2,3,5,7,11,13,17,19,23,29}; //10int n,mod;int a[SZ],g[SZ],dp[SZ][SZ];void print(int x){ for(int i = 10;i >= 0;i --) printf("%d",x >> i & 1); printf(" ");}void calc(int x){ int xx = x; for(int i = 1;i <= 10;i ++) { int v = pri[i]; if(x % v == 0) { while(x % v == 0) x /= v; a[xx] |= (1 << i); } }}int main(){ scanf("%d%d",&n,&mod); for(int i = 1;i <= n;i ++) calc(i);// for(int i = 0;i <= MAXC;i ++)// print(i),printf("%d\n",g[i]); dp[0][0] = 1; for(int i = 2;i <= n;i ++) { for(int j = MAXC;j >= 0;j --) { for(int k = MAXC;k >= 0;k --) { if((a[i] & k) == 0) dp[j | a[i]][k] = (dp[j | a[i]][k] + dp[j][k]) % mod; if((a[i] & j) == 0) dp[j][k | a[i]] = (dp[j][k | a[i]] + dp[j][k]) % mod; } } } int ans = 0; for(int i = MAXC;i >= 0;i --) { for(int j = MAXC;j >= 0;j --) { if((i & j) == 0) { // if(dp[i][j]) // print(i),print(j),printf("%d\n",dp[i][j]); ans = (ans + dp[i][j]) % mod; } } } printf("%d",ans); return 0;}
100分:
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;typedef long long LL;const int SZ = 5010;const int MAXC = 1 << 8;int pri[233] = {2,3,5,7,11,13,17,19}; //10int n,mod;struct haha{ int a,p;}l[SZ];bool operator <(haha a,haha b){ return a.p < b.p;}int dp[SZ][SZ][2];int f[SZ][SZ];void print(int x){ for(int i = 10;i >= 0;i --) printf("%d",x >> i & 1); printf(" ");}void calc(int x){ int xx = x; for(int i = 0;i < 8;i ++) { int v = pri[i]; if(x % v == 0) { while(x % v == 0) x /= v; l[xx].a |= (1 << i); } } l[xx].p = x;}int main(){ scanf("%d%d",&n,&mod); for(int i = 2;i <= n;i ++) calc(i);// for(int i = 0;i <= MAXC;i ++)// print(i),printf("%d\n",g[i]); sort(l + 2,l + n + 1); f[0][0] = 1; for(int i = 2;i <= n;i ++) { if(i == 2 || l[i].p == 1 || l[i].p != l[i - 1].p) for(int j = MAXC;j >= 0;j --) for(int k = MAXC;k >= 0;k --) dp[j][k][0] = dp[j][k][1] = f[j][k]; for(int j = MAXC;j >= 0;j --) { for(int k = MAXC;k >= 0;k --) { if((l[i].a & k) == 0) dp[j | l[i].a][k][0] = (dp[j | l[i].a][k][0] + dp[j][k][0]) % mod; if((l[i].a & j) == 0) dp[j][k | l[i].a][1] = (dp[j][k | l[i].a][1] + dp[j][k][1]) % mod; } } if(i == n || l[i].p == 1 || l[i].p != l[i + 1].p) for(int j = MAXC;j >= 0;j --) for(int k = MAXC;k >= 0;k --) f[j][k] = ((LL)dp[j][k][0] + dp[j][k][1] - f[j][k]) % mod; } int ans = 0; for(int i = MAXC;i >= 0;i --) { for(int j = MAXC;j >= 0;j --) { if((i & j) == 0) { ans = (ans + f[i][j]) % mod; } } } printf("%d",(ans + mod) % mod); return 0;}/*30 30*/
- 【bzoj4197】[Noi2015]寿司晚宴 状压DP
- 【BZOJ4197】[Noi2015]寿司晚宴【状压DP】【背包】
- [NOI2015][BZOJ4197][状压DP]寿司晚宴
- bzoj4197[Noi2015]寿司晚宴 [状压DP]
- bzoj4197 [NOI2015] [状压dp] 寿司晚宴
- BZOJ4197: [Noi2015]寿司晚宴 状压DP
- 【bzoj4197】[Noi2015]寿司晚宴 dp
- BZOJ4197 [Noi2015]寿司晚宴
- bzoj4197 [Noi2015]寿司晚宴
- 【bzoj4197】[Noi2015]寿司晚宴
- Bzoj4197: [Noi2015]寿司晚宴
- 【bzoj4197】【NOI2015】寿司晚宴
- 【NOI2015】【bzoj4197】【状压DP】【滚动数组】寿司晚宴
- 【NOI2015】【寿司晚宴】【状压DP】
- NOI2015 寿司晚宴 状压DP
- bzoj 4197: [Noi2015]寿司晚宴 状压dp
- [BZOJ 4197][Noi2015]寿司晚宴:状压DP
- BZOJ 4197([Noi2015]寿司晚宴-状压dp)
- 详解spring mvc 3.0常用注解
- springMVC-2
- leetcode:Rotate Image 【Java】
- IDA入门(1)
- Hdu 2073 无限的路【数学】
- 【bzoj4197】[Noi2015]寿司晚宴 状压DP
- 在Hadoop上安装HBase
- tinyos learning on day 3
- 前端工程与性能优化
- 在Hadoop上安装Hive
- HDU 1081:To The Max
- 求个人所得税和税后收入
- ubuntu14.04搭建hadoop伪集群环境
- SVM入门简介(1)