博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ1004】【HNOI2008】Cards 群论 置换 burnside引理 背包DP
阅读量:5327 次
发布时间:2019-06-14

本文共 1946 字,大约阅读时间需要 6 分钟。

题目描述

  有\(n\)张卡牌,要求你给这些卡牌染上RGB三种颜色,\(r\)张红色,\(g\)张绿色,\(b\)张蓝色。

  还有\(m\)种洗牌方法,每种洗牌方法是一种置换。保证任意多次洗牌都可用这\(m\)种洗牌法中的一种代

替,且对每种洗牌法,都存在一种洗牌法使得能回到原状态。

  问你本质不同的染色方法有多少种。

  \(r,g,b\leq 20,m\leq 60\)

题解

  对照置换群的定义,可以发现这\(m\)种置换加上恒等置换一共\(m+1\)中置换构成了一个置换群。

  由burnside引理得到本质不同的方案数就是只考虑每个置换时的染色方案数的平均数。

  对于每个置换,先处理出循环,一个循环里的卡牌要染上相同的颜色。因为每种颜色的卡牌有数量限制,所以要背包DP一下。

  最后乘上\({(m+1)}^{-1}\)

  时间复杂度:\(O(n^3m)\)

代码

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair
pii;typedef pair
pll;void sort(int &a,int &b){ if(a>b) swap(a,b);}void open(const char *s){#ifndef ONLINE_JUDGE char str[100]; sprintf(str,"%s.in",s); freopen(str,"r",stdin); sprintf(str,"%s.out",s); freopen(str,"w",stdout);#endif}int rd(){ int s=0,c; while((c=getchar())<'0'||c>'9'); do { s=s*10+c-'0'; } while((c=getchar())>='0'&&c<='9'); return s;}int upmin(int &a,int b){ if(b
a) { a=b; return 1; } return 0;}int p;int fp(int a,int b){ int s=1; for(;b;b>>=1,a=a*a%p) if(b&1) s=s*a%p; return s;}int f[100][100][100];int a[100];int r,g,b;int n;int c[100];void add(int &a,int b){ a=(a+b)%p;}void dp(int v){ int i,j,k; for(i=r;i>=0;i--) for(j=g;j>=0;j--) for(k=b;k>=0;k--) { if(i>=v) add(f[i][j][k],f[i-v][j][k]); if(j>=v) add(f[i][j][k],f[i][j-v][k]); if(k>=v) add(f[i][j][k],f[i][j][k-v]); }}int solve(){ memset(f,0,sizeof f); f[0][0][0]=1; int i; memset(c,0,sizeof c); for(i=1;i<=n;i++) { int s=0; int j=i; while(!c[j]) { c[j]=1; s++; j=a[j]; } dp(s); } return f[r][g][b];}int main(){ int m; scanf("%d%d%d%d%d",&r,&g,&b,&m,&p); int i,j; n=r+g+b; int ans=0; for(i=1;i<=m;i++) { for(j=1;j<=n;j++) scanf("%d",&a[j]); add(ans,solve()); } m++; for(i=1;i<=n;i++) a[i]=i; add(ans,solve()); ans=ans*fp(m,p-2)%p; printf("%d\n",ans); return 0;}

转载于:https://www.cnblogs.com/ywwyww/p/8513453.html

你可能感兴趣的文章
windows 安装yaml支持和pytest支持等
查看>>
读书笔记:季羡林关于如何做研究学问的心得
查看>>
面向对象的优点
查看>>
套接口和I/O通信
查看>>
阿里巴巴面试之利用两个int值实现读写锁
查看>>
浅谈性能测试
查看>>
Winform 菜单和工具栏控件
查看>>
CDH版本大数据集群下搭建的Hue详细启动步骤(图文详解)
查看>>
巧用Win+R
查看>>
浅析原生js模仿addclass和removeclass
查看>>
Python中的greenlet包实现并发编程的入门教程
查看>>
java中遍历属性字段及值(常见方法)
查看>>
深入理解jQuery框架-框架结构
查看>>
YUI3自动加载树实现
查看>>
python知识思维导图
查看>>
当心JavaScript奇葩的逗号表达式
查看>>
App Store最新审核指南(2015年3月更新版)
查看>>
织梦MIP文章内容页图片适配百度MIP规范
查看>>
点击复制插件clipboard.js
查看>>
[Kali_BT]通过低版本SerialPort蓝牙渗透功能手机
查看>>