[置换群+背包] BZOJ1004: [HNOI2008]Cards
2017-04-09 19:43
417 查看
题意
小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红,蓝,绿。小春发明了M种不同的洗牌法,问Sun有多少种不同的染色方案。
两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方法可以使用多次)洗成另一种。
输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代
替,且对每种洗牌法,都存在一种洗牌法使得能回到原状态。
答案可能很大,只要求出答案除以P的余数(P为质数).
题解
完全裸的一个置换群模型。只需要注意到各种颜色数是有规定的,显然不能直接3nc(g) 直接得到对某置换g保持不变的的方案数。那如何做呢?对于某个置换g,若某一着色方案对g保持不变,那么它对应g中的各个循环节中的元素都必须染成同样的颜色。
这样就可以转化成背包求方案数了。设f[i][j][k] 表示染了i个红色,j个蓝色,k个绿色的方案数。转移就是把某个循环节的元素全部涂成某一种颜色。最后有除法,求一下逆元就好了。
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=75; int allv[3],n,m,MOD,a[maxn][maxn],ans,f[maxn][maxn][maxn],w[maxn]; bool vis[maxn]; int get(int id){ memset(w,0,sizeof w); memset(vis,0,sizeof vis); for(int i=1;i<=n;i++) if(!vis[i]){ w[0]++; int now=i; do w[w[0]]++, vis[now]=true, now=a[id][now]; while(!vis[now]); } memset(f,0,sizeof f); f[0][0][0]=1; for(int i=1;i<=n;i++) for(int j0=allv[0];j0>=0;j0--) for(int j1=allv[1];j1>=0;j1--) for(int j2=allv[2];j2>=0;j2--){ int &fnow=f[j0][j1][j2]; if(j0>=w[i]) fnow=(fnow+f[j0-w[i]][j1][j2])%MOD; if(j1>=w[i]) fnow=(fnow+f[j0][j1-w[i]][j2])%MOD; if(j2>=w[i]) fnow=(fnow+f[j0][j1][j2-w[i]])%MOD; } return f[allv[0]][allv[1]][allv[2]]; } int power(int a,int b){ if(!b) return 1; if(b&1) return (a*power(a,b-1))%MOD; int t=power(a,b/2); return (t*t)%MOD; } int main(){ freopen("bzoj1004.in","r",stdin); freopen("bzoj1004.out","w",stdout); scanf("%d%d%d%d%d",&allv[0],&allv[1],&allv[2],&m,&MOD); n=allv[0]+allv[1]+allv[2]; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]); m++; for(int j=1;j<=n;j++) a[m][j]=j; for(int i=1;i<=m;i++) ans=(ans+get(i))%MOD; ans=(ans*power(m,MOD-2))%MOD; printf("%d\n",ans); return 0; }
相关文章推荐
- BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )
- [BZOJ1004][HNOI2008]Cards(置换群+背包+乘法逆元)
- 【BZOJ1004】【HNOI2008】Cards(群论、Burnside引理、背包dp)
- [BZOJ1004]HNOI2008 Cards |polya|置换群|DP|乘法逆元
- 【置换群】【bzoj 1004】: [HNOI2008]Cards
- BZOJ 1004([HNOI2008]Cards-Polya计数+k背包)
- bzoj1004 [HNOI2008]Cards(burnside引理+背包dp)
- 置换群burnside引理(bzoj 1004: [HNOI2008]Cards)
- BZOJ1004 [HNOI2008]Cards(置换群+dp)
- 【BZOJ1004】【HNOI2008】Cards 群论 置换 burnside引理 背包DP
- BZOJ 1004([HNOI2008]Cards-Polya计数+k背包)
- [bzoj1004][HNOI2008][Cards] (置换群+Burnside引理+动态规划)
- [BZOJ1004][HNOI2008][Burnside引理][DP]Cards
- BZOJ 1004 HNOI2008 Cards Burnside引理
- 【BZOJ 1004】 [HNOI2008]Cards
- 【BZOJ】【1004】【HNOI2008】Cards
- 【BZOJ 1004】【HNOI 2008】Cards
- kyeremal-bzoj1004-[HNOI2008]-cards-dp+polya
- [BZOJ1004][HNOI2008]Cards(Burnside引理+DP)
- [BZOJ 1004] [HNOI2008] Cards 【Burnside引理 + DP】