ACM-ICPC 2017 Asia Xi'an J LOL 【暴力 && 排列组合】
任意门:https://nanti.jisuanke.com/t/20750
J - LOL
5 friends play LOL together . Every one should BAN one character and PICK one character . The enemy should BAN 5 characters and PICK 5 characters . All these 20 heroes must be different .
Every one can BAN any heroes by his personal washes . But he can only PICK heroes which he has bought .
Suppose the enemy can PICK or BAN any heroes. How many different ways are there satisfying the conditions?
For example , a valid way is :
Player 1 : picks hero 1, bans hero 2
Player 2 : picks hero 3, bans hero 4
Player 3 : picks hero 5, bans hero 6
Player 4 : picks hero 7, bans hero 8
Player 5 : picks hero 9, bans hero 10
Enemies pick heroes 11,12,13,14,15 , ban heroes 16,17,18,19,20 .
Input
The input contains multiple test cases.(No more than 20)
In each test case . there’s 5 strings S[1]∼S[5] ,respectively whose lengths are 100 , For the i-th person if he has bought the j-th hero, the j-th character of S[i] is '1', or '0' if not. The total number of heroes is exactly 100 .
Output
For each test case , print the answer mod 1000000007 in a single line .
样例输入
0110011100011001001100011110001110001110001010010111111110101010010011010000110100011001001111101011 1000111101111110110100001101001101010001111001001011110001111110101000011101000001011100001001011010 0100101100011110011100110110011100111100010010011001111110101111111000000110001110000110001100001110 1110010101010001000110100011101010001010000110001111111110101010000000001111001110110101110000010011 1000010011111110001101100000101001110100011000111010011111110110111010011111010110101111011111011011
样例输出
515649254
题意概括:
五个二进制数代表我方 5 人所拥有的英雄,0为没有,1为有。
敌方5人什么英雄都有,问有多少种 Ban Pick方案。
每人都可以选一个自己拥有的英雄和 ban 掉任何一个英雄,最后选的和禁止掉的20个英雄都不相同。
解题思路:
暴力枚举我方选英雄的方案
敌方选英雄的方案为 A(95, 5)
我方禁英雄的方案为 C(90, 5)
敌方禁英雄的方案为 C(85,5)
关于暴力的优化和剪枝:
如果是传统暴力枚举每个人选不同英雄的方案,需要五层 for(0, 100) 循环,TL!
优化只枚举前四个人的方案, 第五个能选的英雄只能是前面没有选的,缩小了一层循环。
关于剪枝 前面选过的不要选咯
AC code:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #define INF 0x3f3f3f3f 6 #define LL long long 7 using namespace std; 8 const int mod = 1e9+7; 9 const int MAXN = 105; 10 11 char a[MAXN], b[MAXN], c[MAXN], d[MAXN], e[MAXN]; 12 LL A(LL N, LL R) 13 { 14 LL sum = 1; 15 for(int i = 0; i < R; i++) 16 sum *= N-i; 17 return sum; 18 } 19 20 LL C(LL N, LL R) 21 { 22 LL sum = 1; 23 for(int i = 1; i <= R; i++) 24 sum = sum* (N+1-i)/i; 25 return sum; 26 } 27 28 int main() 29 { 30 while(~scanf("%s%s%s%s%s", a, b, c, d, e)){ 31 int len = 0; 32 for(int i = 0; i < 100; i++){ 33 if(e[i] == '1') len++; 34 } 35 LL ans = 0; 36 for(int i = 0; i < 100; i++){ 37 if(a[i] == '0') continue; 38 for(int j = 0; j < 100; j++){ 39 if(b[j] == '0' || j == i) continue; 40 for(int k = 0; k < 100; k++){ 41 if(c[k] == '0' || k == i || k == j) continue; 42 for(int p = 0; p < 100; p++){ 43 if(d[p] == '0' || p == i || p == j || p == k) continue; 44 int res = len; 45 if(e[i] == '1') res--; 46 if(e[j] == '1') res--; 47 if(e[k] == '1') res--; 48 if(e[p] == '1') res--; 49 if(res>=0) ans+=res; 50 } 51 } 52 } 53 } 54 ans = ans*A(95, 5)%mod*C(90, 5)%mod*C(85, 5)%mod; 55 printf("%lld\n", ans); 56 } 57 return 0; 58 }