【暴力+剪枝】 2017ICPC 西安 J LOL
阿新 • • 發佈:2018-12-12
5個人,一共有100個英雄,0代表他沒有,1代表他有
敵方什麼英雄都有
我方和敵方都可以選擇五個英雄BAN和PICK,也就是20個英雄不一樣
解題方法:枚舉出我方前四個人的選擇英雄的情況,先預存第五個人的英雄數量,前四個人選的英雄要是我也有,就數量--,
那麼我還有幾個就是有多少種情況
我方五個人選的英雄的每一種情況都可以*A(95,5)*C(90,5)*C(85,5)
A(95,5):敵方選擇的英雄種類,重點在於順序可以不一樣,
C(90,5):我方BAN掉的英雄種類
C(85,5):敵方BAN掉的英雄種類
#include <bits/stdc++.h> #define ll long long using namespace std; const int mod=1e9+7; char a[105],b[105],c[105],d[105],e[105]; ll A(ll n, ll r)//排列數 { ll sum = 1; for (int i = 0; i < r; i++) sum *= n-i; return sum; } ll C(ll n, ll r)//組合數 { ll sum = 1; for (int i = 1; i <= r; i++) sum = sum * (n+1-i)/i; return sum; } int main() { while(~scanf("%s%s%s%s%s",a,b,c,d,e)) { int l1=0,l2=0,l3=0,l4=0,l5=0; for(int i=0;i<100;i++) { if(a[i]=='1') l1++; if(b[i]=='1') l2++; if(c[i]=='1') l3++; if(d[i]=='1') l4++; if(e[i]=='1') l5++; } ll ans=0; for(int i=0;i<100;i++) { if(a[i]=='0') continue; for(int j=0;j<100;j++) { if(b[j]=='0'||i==j) continue; for(int k=0;k<100;k++) { if(c[k]=='0'||k==i||k==j) continue; for(int p=0;p<100;p++) { int q=l5; if(d[p]=='0'||p==i||p==j||p==k) continue; if(e[i]=='1') q--; if(e[j]=='1') q--; if(e[k]=='1') q--; if(e[p]=='1') q--; if(q>=0) ans+=q; } } } } ans=ans*A(95,5)%mod*C(90,5)%mod*C(85,5)%mod; printf("%lld\n",ans); } return 0; } /* 0110011100011001001100011110001110001110001010010111111110101010010011010000110100011001001111101011 1000111101111110110100001101001101010001111001001011110001111110101000011101000001011100001001011010 0100101100011110011100110110011100111100010010011001111110101111111000000110001110000110001100001110 1110010101010001000110100011101010001010000110001111111110101010000000001111001110110101110000010011 1000010011111110001101100000101001110100011000111010011111110110111010011111010110101111011111011011 515649254 */