zoukankan      html  css  js  c++  java
  • [JSOI2015]染色游戏

    Description

    棋盘是一个n×m的矩形,分成n行m列共n*m个小方格。
    现在萌萌和南南有C种不同颜色的颜料,他们希望把棋盘用这些颜料染色,并满足以下规定:
    1.棋盘的每一个小方格既可以染色(染成C种颜色中的一种),也可以不染色。
    2.棋盘的每一行至少有一个小方格被染色。
    3.棋盘的每一列至少有一个小方格被染色。
    4.每种颜色都在棋盘上出现至少一次。
    请你求出满足要求的不同的染色方案总数。只要存在一个位置的颜色不同,
    即认为两个染色方案是不同的

    Input

    输入只有一行 3 个整数n,m,c。1 < = n,m,c < = 400

    Output

    输出一个整数,为不同染色方案总数。
    因为总数可能很大,只需输出总数mod 1,000,000,007的值。

    Sample Input

    2 2 3

    Sample Output

    60


    题解

    容斥
    枚举至多有(k)种颜色被使用
    然后发现还是不能求出答案
    那就继续容斥
    至多(i)行被染色
    至多(j)列被染色
    然后答案就是((-1)^{n+m+c-i-j-k} imes C_{n}^{i} imes C_{m}^{j} imes C_{c}^{k} imes (k+1)^{i imes j})

    代码

    #include<cstdio>
    const int M = 405 ;
    const int mod = 1e9 + 7 ;
    using namespace std ;
    
    int n , m , c , ans , C[M][M] , pw[M][M * M] ;
    int main() {
    	scanf("%d%d%d",&n,&m,&c) ;
    	for(int i = 0 ; i <= 400 ; i ++) {
    		C[i][0] = 1 ;
    		for(int j = 1 ; j <= i ; j ++) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod ;
    	}
    	for(int i = 1 ; i <= c + 1 ; i ++) {
    		pw[i][0] = 1 ;
    		for(int j = 1 ; j <= n * m ; j ++) pw[i][j] = 1LL * pw[i][j - 1] * i % mod ;
    	}
    	for(int i = n ; i >= 0 ; i --)
    		for(int j = m ; j >= 0 ; j --)
    			for(int k = c ; k >= 0 ; k --)
    				ans = (ans + 1LL * ( (n + m + c - i - j - k) % 2 ? ( mod - 1 ) : 1 ) * C[n][i] % mod * C[m][j] % mod * C[c][k] % mod * pw[k + 1][i * j] % mod) % mod ;
    	printf("%d
    ",ans) ;
    	return 0 ;
    }
    
  • 相关阅读:
    #背包#nssl 1488 上升子序列
    #环#nssl 1487 图
    #分治#JZOJ 4211 送你一颗圣诞树
    #概率,dp#JZOJ 4212 我想大声告诉你
    #并查集#JZOJ 4223 旅游
    #dp#nssl 1478 题
    #对顶堆#nssl 1477 赛
    #线段树,离散#nssl 1476 联
    #折半搜索,状压dp#nssl 1471 Y
    #并查集,线性筛#nssl 1470 X
  • 原文地址:https://www.cnblogs.com/beretty/p/10771347.html
Copyright © 2011-2022 走看看