zoukankan      html  css  js  c++  java
  • Gym-101194H Great Cells 思维,组合计数

    Gym-101194H Great Cells 思维,组合计数

    题意

    给定(N imes M)的矩阵。

    定义好点为,该点的大小严格大于该行和该列的每个其他格子的大小。

    现可在每个点赋值([1,K])。记(A_g)为好点个数的(g)的赋值方案数。

    [sum_{g=0}^{NM}(g+1)cdot A_g mod(1e9+7) ]

    [1 leq T leq 20\ 1leq N,M,k leq200 ]

    分析

    一眼DP,发现太复杂。观察式子,可以拆为

    [A_g + gcdot A_g ]

    对前面的求和明显就是总方案数(K^{NM})

    后面的我们利用系数(g)启发,可以理解为答案把每个好点都贡献一遍(A_g),那么总的来看,每个好点的贡献就是这个好点的总方案数,这个的计算方法只需要枚举这个点做为好点时的大小,它会限制(N+M-2)个点,其余的点随意。

    故答案为

    [NMsum_{i=2}^K(i-1)^{NM-2} imes K^{(N-1)(M-1)} + K^{NM} ]

    代码

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    using namespace std;
    typedef long long ll;
    
    const ll MOD = 1e9 + 7;
    
    ll rd(){
    	ll x = 0;
    	int f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9'){
    		if(ch == '-')  f = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9'){
    		x =x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return x * f;
    } 
    
    ll ksm(ll a,ll b,ll m){
    	ll ans = 1;
    	ll base = a;
    	while(b){
    		if(b & 1) {
    			ans *= base;
    			ans %= m;
    		}
    		base *= base;
    		base %= m;
    		b >>= 1;
    	}
    	return ans;
    }
    
    int main(){
    	int kase = 0;
    	int T = rd();
    	while(T--){
    		int n = rd();
    		int m = rd();
    		int k = rd();
    		ll ans = 0;
    		for(int i = 2;i <= k;i++){
    			ans += ksm(i - 1,n + m - 2,MOD) * ksm(k,n * m - n - m + 1,MOD) % MOD;
    			ans %= MOD; 
    		}		
    		ans *= n * m;
    		ans %= MOD;
    		ans += ksm(k,n * m,MOD);
    		ans %= MOD;
    		printf("Case #%d: %lld
    ",++kase,ans);
    	}
    }
    
  • 相关阅读:
    将已排序的数组乱序
    Roadmap!!
    测试
    最大对称字串
    约瑟夫环问题
    大家好
    MYSQL数据库导入SQL文件出现乱码如何解决
    Hibernate缓存
    Spring备忘四(涵盖Spring2.5)
    Struts2 Hello,Wold
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14476997.html
Copyright © 2011-2022 走看看