vijos - P1286座位安排 (DP狀態壓縮 + 組合數 + python)

來源:互聯網
上載者:User

標籤:

P1286座位安排Accepted標籤:[顯示標籤]背景

快要期中考試了!老師需要hzy幫他排考試的座位。。。

描述

考場裡的座位恰好有n行m列,並且恰好有n*m位考生在這個考場裡面考試,也就是說,所有的座位上都有考生。hzy根據學校記載,有k位考生可能作弊,因此hzy不能讓他們之中的任何兩個人做在相鄰的座位上!所謂相鄰的座位,即在同一行相鄰列或者在同一列的相鄰行的座位。hzy準備這樣安排座位,首先隨機播放一種方案,如果這種方案是合法的,就用這種方案,否則重新選擇。你的任務是計算,他得到一個合法方案時,需要的期望選擇次數。

格式輸入格式

輸入檔案為一行,僅包含三個整數n,m和k。

輸出格式

如果不存在合法的方案,則輸出檔案seating.out中應該包含Impossible!,否則輸出一個分數p/q,表示期望選擇次數(即平均次數),這裡p和q應該是互質的。

範例1範例輸入1[複製]
1 4 3
範例輸出1[複製]
Impossible!
範例2範例輸入2[複製]
2 3 2
範例輸出2[複製]
15/8
提示

1≤n≤80,1≤m≤80,1≤n*m≤80

0≤k≤20,並且k≤n*m

對於題目狀態壓縮很明顯,然後是對於組合數,組合數是我的弱點,高中知識基本都忘得差不多了

提示一下:C(m,n) = n!/(m! * (n - m)!)  -> n*(n-1)*(n-2)....(n-m+1)/m!(這裡的k比較小,所以這麼轉換,如果是n-m比較小則可以轉換為:n*(n-1)*(n-2).....*(m+1)/(n-m)!)

如此其他的就是狀態壓縮的過程了


#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;LL dp[80 + 5][20 + 5][1 << 12];int n, m, k;LL gcd(LL a,LL b) {    return b? gcd(b, a % b) : a;}bool C(int mm,int s) {    for(int i = 0; i < 15; i ++) {        if((s & (1 << i)) && (mm & (1 << i))) return false;    }    return true;}bool CC(int s) {    int bits[15] = {0},cnt = 0;    while(s) {        bits[cnt ++] = (s & 1);        s >>= 1;    }    for(int i = 1; i < cnt; i ++) {        if(bits[i] + bits[i - 1] >= 2)return false;    }    return true;}LL CS(LL c, LL s) {    LL ret = 1;    for(int i = 1; i <= s; i ++) ret = ret * (c - i + 1) / i;    return ret;}void CSS(LL nn,LL kk,LL x) {    LL xi = 1,sh = 1,f;    for(int i = 1; i <= kk; i ++) xi *= i;    for(int i = nn - kk + 1; i <= nn; i ++ ) {        sh *= i;        f = gcd(sh,xi);        sh /= f;        xi /= f;    }    xi *= x;    f = gcd(xi,sh);    xi /= f;    sh /= f;    printf("%I64d/%I64d\n",sh,xi);}int main() {    scanf("%d%d%d", &n, &m, &k);    if(m > n) swap(n, m);    dp[0][0][0] = 1;//第幾行安排了多少人了,以及此時要安裝的人數    for(int i = 1; i <= n; i ++) {        for (int j = 0; j <= k; j ++) {            for(int s = 0; s < (1 << m); s ++) {                if(!CC(s)) continue;                int bits = 0,ft = s;                while(ft) {                    bits += (ft & 1);                    ft >>= 1;                }                for(int ks = 0 ; ks < (1 << m); ks ++) {                    if(!CC(ks)) continue;                    if(!C(ks,s)) continue;                    if(j - bits < 0) continue;                    dp[i][j][s] += dp[i - 1][j - bits][ks];                }            }        }    }    LL ret = 0;    for(int i = 0; i < (1 << m); i ++) {        ret += dp[n][k][i];    }    if(ret <= 0) {        printf("Impossible!\n");    } else {        CSS(n * m, k, ret);    }    return 0;}


著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

vijos - P1286座位安排 (DP狀態壓縮 + 組合數 + python)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.