首页 > 代码库 > uva 11806 Cheerleaders(容斥)
uva 11806 Cheerleaders(容斥)
题意:如何摆放拉拉队的问题,在矩形网格m*n中,k名拉拉队员,要求四周网格中each side有至少一名拉拉队员,corner有人算两边,问有多少种摆法?
思路:容斥;
c[m*n][k] -- c[(n-1)*m][k] U c[(n-1)*m][k]U c[n*(m-1)][k] U c[n*(m-1)][k]
#include<cstdio> #include<iostream> #include<cstring> #define mod 1000007 using namespace std; typedef long long LL; //int C1[500][500]; int C[500][500]; void pre() //递推组合C[ ][ ] { memset(C,0,sizeof C); C[0][0]=1; for(int i=1;i<=400;i++) { C[i][i]=C[i][0]=1; for(int j=1;j<i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod; } } int solve(int M,int N,int k) //容斥 { int sum=0; for(int i=1;i<(1<<4);i++) //枚举 { int n=N,m=M,bits=0; if(i&1) { bits++; n--; } if(i&(1<<1)) { bits++; m--; } if(i&(1<<2)) { bits++; n--; } if(i&(1<<3)) { bits++; m--; } if(bits%2==1) //判断奇偶 sum=(sum+C[n*m][k])%mod; else sum=(sum-C[n*m][k])%mod; } return ((C[N*M][k]-sum)%mod+mod)%mod; } int main() { int T; cin>>T; pre(); for(int cas=1;cas<=T;cas++) { int n,m,k; cin>>n>>m>>k; printf("Case %d: ",cas); if(k>n*m) printf("0\n"); else printf("%d\n",solve(n,m,k)); } return 0; }
uva 11806 Cheerleaders(容斥)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。