程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA11806-Cheerleaders(容斥原理+二進制)

UVA11806-Cheerleaders(容斥原理+二進制)

編輯:C++入門知識

UVA11806-Cheerleaders(容斥原理+二進制)


題目鏈接


題意:在一個m*n的矩形網格裡放k個相同的石子,問有多少種方法?每個格子最多放一個石子,所有石子都要放完,並且第一行、最後一行、第一列、最後一列都得有石子。

思路:假設滿足第一行沒有石子的方案集為A,最後一行沒有石子的方案集為B,第一列沒有石子的方案集為C,最後一列沒有石子的方案集為D,全集為S,則所求答案就是“在S中但不在A,B,C,D任何一個集合中”的元素個數,這裡就是運用容斥原理。程序中可以用二進制來表示集合。

代碼:

#include 
#include 
#include 
#include 
#include 

using namespace std;

const int MAXN = 510;
const int MOD = 1000007;

int C[MAXN][MAXN];
int n, m, k;

void init() {
    memset(C, 0, sizeof(C));
    C[0][0] = 1;
    for (int i = 0; i < MAXN; i++) {
        C[i][0] = C[i][i] = 1; 
        for (int j = 1; j < i; j++)
            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD;
    }
}

int main() {
    init();
    int cas, t = 1;
    scanf("%d", &cas);
    while (cas--) {
        scanf("%d%d%d", &n, &m, &k); 
        int sum = 0; 
        for (int S = 0; S < 16; S++) {
            int b = 0, r = n, c = m;  
            for (int i = 0; i < 4; i++) {
                if (S & (1 << i)) {
                    if (i % 2)
                        r--;
                    else
                        c--;
                    b++;
                } 
            }
            if (b & 1)
                sum = (sum + MOD - C[r * c][k]) % MOD;
            else
                sum = (sum + C[r * c][k]) % MOD;
        }
        printf("Case %d: %d\n", t++, sum);
    }
    return 0;
}



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved