zoukankan      html  css  js  c++  java
  • [HNOI2008]Cards

    题目

    洛谷
    BZOJ

    做法

    一种置换各个循环里的颜色相同,这个手玩就懂了(唯一性)

    三维背包就能做,最后再加个不变的一种置换

    My complete code

    #include<bits/stdc++.h>
    using namespace std;
    typedef int LL;
    LL const maxn=30;
    LL r,b,g,m,p,n,ans;
    LL dp[maxn][maxn][maxn],len[maxn*3],a[maxn*3];
    bool visit[maxn*3];
    inline LL Pow(LL base,LL b){
    	LL ret(1);
    	while(b){
    		if(b&1) ret=ret*base%p;
    	    base=base*base%p,b>>=1;
    	}return  ret;
    }
    
    inline LL Dp(){
    	LL cnt(0);
    	memset(visit,false,sizeof(visit));
    	memset(len,0,sizeof(len));
    	memset(dp,0,sizeof(dp));
    	for(LL i=1;i<=n;++i){
    		if(!visit[i]){
    			++cnt;
    			for(LL j=i;!visit[j];j=a[j]) 
    			    visit[j]=true,++len[cnt];
    		}
    	}
    	dp[0][0][0]=1;
    	for(LL i=1;i<=cnt;++i)
    		for(LL R=r;R>=0;--R)
    		    for(LL B=b;B>=0;--B)
    		        for(LL G=g;G>=0;--G){
    		        	if(R>=len[i]) dp[R][B][G]=(dp[R][B][G]+dp[R-len[i]][B][G])%p;
    		        	if(B>=len[i]) dp[R][B][G]=(dp[R][B][G]+dp[R][B-len[i]][G])%p;
    		        	if(G>=len[i]) dp[R][B][G]=(dp[R][B][G]+dp[R][B][G-len[i]])%p;
    				}
    	return dp[r][b][g];
    }
    int main(){
    	scanf("%d%d%d%d%d",&r,&b,&g,&m,&p);
    	n=r+b+g;
    	for(LL i=1;i<=m;++i){
    		for(LL j=1;j<=n;++j) scanf("%d",a+j);
    		ans=(ans+Dp())%p;
    	}
    	for(LL i=1;i<=n;++i) a[i]=i;
    	ans=(ans+Dp())%p;
    	printf("%d",ans*Pow(m+1,p-2)%p);
    	return 0;
    }
    
  • 相关阅读:
    【模板】Sparse-Table
    UVa 11235 Frequent values
    【模板】树状数组
    UVa 1428 Ping pong
    数学技巧
    UVa 11300 Spreading the Wealth
    UVa 11729 Commando War
    UVa 11292 Dragon of Loowater
    POJ 3627 Bookshelf
    POJ 1056 IMMEDIATE DECODABILITY
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10365787.html
Copyright © 2011-2022 走看看