P1286Seating arrangement accepted Label: [Show label]<textarea id="code" class="textbox" style=""></textarea>Background
It's going to midterm! The teacher needs Hzy to help him arrange the seat of the exam ...
Describe
The seats in the examination room happen to have n rows of M, and there are n*m candidates in the examination hall, that is to say, all the seats have candidates. Hzy according to the school records, there are k candidates may cheat, so hzy can not let any of them two people in the adjacent seat! The so-called adjacent seats, that is, in the same row adjacent columns or adjacent rows in the same column of the seat. Hzy is prepared to arrange the seats in this way, first randomly choosing a scheme, if the scheme is legal, use this option, or re-choose. Your task is to calculate the number of desired choices that he will need when he gets a legit scheme.
Format input Format
The input file is a row and contains only three integers n,m and K.
Output format
If there is no valid scheme, the output file seating.out should contain impossible!, otherwise output a fractional p/q, indicating the desired number of times (that is, the average number of times), where p and Q should be coprime.
Example 1 sample input 1[copy]
1 4 3
Sample output 1[Copy]
impossible!
Example 2 sample input 2[copy]
2 3 2
Sample output 2[Copy]
15/8
Tips
1≤n≤80,1≤m≤80,1≤n*m≤80
0≤k≤20, and K≤n*m
For the problem of state compression is obvious, and then for the combination number, the combination number is my weakness, high school knowledge basically forget almost
Tip: C (m,n) = n!/(m! * (N-M)!) * N (n-1) * (n-2) .... (n-m+1)/m! (k here is relatively small, so the conversion, if the n-m is relatively small can be converted to: N (n-1) * (n-2) ..... * (m+1)/(N-M)!)
So the rest is the process of state compression.
#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 < 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;//How many people are arranged in the first few lines, and the number of persons to be installed at this time 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;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
vijos-p1286 seating Arrangement (DP State compression + combo + python)