题意:有n张牌,有R+G+B=n的3种颜色及其数量,要求用这三种颜色去染n张牌。n张牌有m中洗牌方式,问在不同洗牌方式下本质相同的染色方案数。

解法:这道题非常有意思,题解参考Hzwer学长的。我这里再总结一下:

看到本质相同的染色方案我们很容易会想到Burnside引理和Polya定理,但是这题不能用Polya定理,为什么?因为一般的Ployd染色的颜色个数是没有限制的,于是当循环节为l颜色为c时候,方式数就是c^l(就是因为一个循环方案要相同所以染的颜色也要相同)。但是此题颜色个数有限制,不能直接每个格子有c种选择,所以不能使用Polyd定理。

那现在我们还是得保证一个循环内颜色相同但又不用Ployd呢?我们使用Burnside引理:可以想象成这样,我们必须要有R个红色,G个绿色,B个蓝色,且每一个循环节我们可以选择它染成R/G/B。那这不就是一个01背包模型,每个循环节就是一个物品,RGB就是容量限制,那么我们就可以用01背包计算方案数即可。

细节见代码及其注释。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=;
int n,r,g,b,m,P,a[],d[]; void exgcd(int a,int b,int& d,int& x,int& y) { //ax+by=gcd(a,b)
if (!b) { d=a;x=;y=; }
else { exgcd(b,a%b,d,y,x); y-=x*(a/b); }
} bool vis[];
LL dp[][N][N][N]; //dp[l][i][j][k]代表前l个循环节组成i个Rj个Gk个B的方案数
LL solve() { //每次计算置换群a的方案数(相当于做一次01背包)
for (int i=;i<=n;i++) vis[i]=;
int num=,now=;
for (int i=;i<=n;i++) { //统计循环节
if (vis[i]) continue;
d[++num]=; now=i; //循环节数量/大小
vis[now]=;
while (!vis[a[now]]) {
d[num]++;
vis[a[now]]=;
now=a[now];
}
}
for (int l=;l<=num;l++) for (int i=;i<=r;i++) for (int j=;j<=g;j++) for (int k=;k<=b;k++)
dp[l][i][j][k]=;
dp[][][][]=; //初始化
for (int l=;l<=num;l++) //循环节个数相当于物品个数
for (int i=;i<=r;i++)
for (int j=;j<=g;j++)
for (int k=;k<=b;k++) {
if (i>=d[l]) dp[l][i][j][k]=(dp[l][i][j][k]+dp[l-][i-d[l]][j][k])%P;
if (j>=d[l]) dp[l][i][j][k]=(dp[l][i][j][k]+dp[l-][i][j-d[l]][k])%P;
if (k>=d[l]) dp[l][i][j][k]=(dp[l][i][j][k]+dp[l-][i][j][k-d[l]])%P;
}
return dp[num][r][g][b];
} int main()
{
scanf("%d%d%d%d%d",&r,&g,&b,&m,&P);
n=r+g+b;
LL ans=;
for (int i=;i<=m;i++) {
for (int j=;j<=n;j++) scanf("%d",&a[j]);
ans+=solve(); //累加所有置换方案数
}
for (int i=;i<=n;i++) a[i]=i;
ans+=solve();
int x,y,d; exgcd(m+,P,d,x,y);
x=(x%P+P)%P; //求出m+1再模P下逆元
cout<<ans*x%P<<endl;
return ;
}

洛谷P1446/BZOJ1004 Cards Burnside引理+01背包的更多相关文章

  1. 洛谷 P4708 - 画画(Burnside 引理+组合数学)

    洛谷题面传送门 神仙题 %%%%%%%%%%%%%%%%%%%% 题解搬运人来了 首先看到本质不同(无标号)的图计数咱们可以想到 Burnside 引理,具体来说,我们枚举一个排列 \(p\),并统计 ...

  2. 洛谷 P1446 [HNOI2008]Cards 解题报告

    P1446 [HNOI2008]Cards 题目描述 小春现在很清闲,面对书桌上的\(N\)张牌,他决定给每张染色,目前小春只有\(3\)种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun ...

  3. luogu P1446 [HNOI2008]Cards burnside引理 置换 不动点

    LINK:Cards 不太会burnside引理 而这道题则是一个应用. 首先 一个非常舒服的地方是这道题给出了m个本质不同的置换 然后带上单位置换就是m+1个置换. burnside引理: 其中D( ...

  4. 洛谷P1441 砝码称重 枚举 + 01背包

    显然,n<=20, m<=4 的数据范围一眼爆搜. 直接搜索一下不用哪4个砝码,再做一遍01背包即可. 可能是本人太菜鸡,01背包部分调了半天QAQ-- #include<cstdi ...

  5. 洛谷P1164小A点菜(01背包)

    题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过uim由于买了一些辅(e ...

  6. 洛谷 P2871 [USACO07DEC]手链Charm Bracelet && 01背包模板

    题目传送门 解题思路: 一维解01背包,突然发现博客里没有01背包的板子,补上 AC代码: #include<cstdio> #include<iostream> using ...

  7. 洛谷P1446 [HNOI2008]Cards

    置换群+dp #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring& ...

  8. 洛谷 P1282 多米诺骨牌("01"背包)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 参考资料: [1]:https://blog.csdn.net/Darost/artic ...

  9. 洛谷——2871[USACO07DEC]手链Charm Bracelet——01背包

    题目描述 Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like t ...

随机推荐

  1. maven推送本地包到私服

    前置要求:配置正确的settings.xml maven 推送 本地jar 到私服的命令示例: mvn deploy:deploy-file -DgroupId=com.oracle -Dartifa ...

  2. 历时小半年总结之JAVA

    一.JavaSE 1.多线程 (1).进程与线程的区别? 答:进程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只是一条执行路径. (2).为什么要用多线程? 答:提高程序效率 (3).多线 ...

  3. ward's method分层聚类凝聚法

    ward's method是分层聚类凝聚法的一种常见的度量cluster之间距离的方法,其基本过程是这样的(参考:http://blog.sciencenet.cn/blog-2827057-9217 ...

  4. Jenkins报错:该Jenkins实例似乎已离线

    解决方法: 1.保留此离线页面,重新开启一个浏览器tab标签页 2.输入输入网址http://localhost:8080/pluginManager/advanced 3.进入该页面最底下,找到[升 ...

  5. PHP Timer 页面运行时间监测类

    转至:http://blog.csdn.net/fdipzone/article/details/20160567 php Timer 页面运行时间监测类,可按不同key监测不同的运行时间 Timer ...

  6. Java的常用类 String

    String类: 代表字符串, java程序中的所有字符串字面值(如, "abc")都是此类的实例实现 String是一个final类,代表不可变的字符序列 字符串是常量是用双引号 ...

  7. 云计算openstack核心组件——keystone身份认证服务

    一.Keystone介绍:       keystone 是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证.令牌的发放和校验.服务列表.用户 ...

  8. Unity3D利用Logcat调试安卓

    发布安卓包之后再次测试发生什么问题很难知道怎么了,比如说出现闪退等情况,可以用Logcat检测到,logcat是Android中一个命令行工具,可以用于得到程序的log信息,可以用 logcat 命令 ...

  9. Codeforces Round #285 (Div. 2)C. Misha and Forest(拓扑排序)

    传送门 Description Let's define a forest as a non-directed acyclic graph (also without loops and parall ...

  10. netcore之mysql中文乱码问题解决记录

    尝试了netcore代码里面设置基本无效了 https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core- ...