hdu 4779 Tower Defense 2013杭州现场赛


  1 /**
2 题意: 有两种塔,重塔,轻塔。每种塔,能攻击他所在的一行和他所在的一列, 轻塔不 能被攻击,而重塔可以被至多一个塔攻击,也就是说重塔只能被重塔攻击。在一个n*m 的矩阵中,最少放一个塔,可放多个
3 问,给定p个重塔,q个轻塔,问有多少种放法。。
4
5 思路: 1、 一行中有两个重塔,
6 2、 一列中有两个重塔
7 3、 在该行及在该行塔所在的列只有一个塔,重塔或者轻塔。
8 对以上三种情况
9 挨个处理:
10 1、 设有i行有两个重塔,j列有两个重塔,则一共占 i+2*j 行, j+2*i列,共用2*(i+j)个重塔,,因为一行或一列两个塔
11 2、 对剩余的塔,进行枚举,0<-->剩余的塔,。。,枚举这些塔中重塔的个数进行枚举
12
13 对于1: 在行中有两个重塔 c(n,i)*c(m,2*i)*((2*i)!/2^i) 意思 是在n行中选i行,在m列中选2*i列, 对于选出来的2*i 列,分成i组,需要进行全排列,但是组内不需要进行全排列。。所以为(2*i)!/2^i
14 在列中有两个重塔,c(m-2*i,j)*c(n-i,2*j)*((2*j)!/2^j) 原理同上
15
16 对于2:设有k个塔, 在剩余的n-(i+2*j) 行 m-(2*i+j) 列中 选 k个 点 ,k最大为 p-2*(i+j)+q
17 对于k个塔,则重塔最多有b = min (k, p-2*(i+j) ) 个, 最少有a = max(0,k-q) 个
18 k个塔,最少 a ,最多b 则为(c[k][0]+c[k][1]...+c[k][b])- (c[k][0]+c[k][1]+...+c[k][a-1]);
19 最后将不放的情况减掉即可,也就是减1;
20 注意: 在计算的过程中注意%mod
21 **/
22
23
24 #include <iostream>
25 #include <algorithm>
26 using namespace std;
27 const long long mod = 1000000007;
28 const int maxn = 220;
29 const long long R = 500000004;
30 long long c[maxn][maxn] ;
31 long long cs[maxn][maxn];
32 long long sq[maxn];
33 long long fac[maxn*2];
34 void init(){
35 c[0][0] =1;
36 for(int i=1;i<maxn;i++){
37 c[i][0] =c[i][i]=1;
38 for(int j=1;j<i;j++){
39 c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod;
40 }
41 }
42 fac[0] =1;
43 for(int i=1;i<maxn*2;i++)
44 fac[i] = (fac[i-1]*i)%mod;
45
46 for(int i=0;i<maxn;i++){
47 cs[i][0] = 1;
48 for(int j=1;j<=i;j++){
49 cs[i][j] = (cs[i][j-1]+c[i][j])%mod;
50 }
51 }
52
53 sq[0] =1;
54 sq[1] =1;
55 long long rr = R;
56 for(int i=2;i<maxn;i++){
57 rr = (rr*R)%mod;
58 sq[i] = (fac[2*i]*rr)%mod;
59 }
60 }
61
62 long long cal(long long n,long long m,long long p){
63 return ((c[n][p]*c[m][2*p])%mod*sq[p])%mod;
64 }
65
66 long long solve(int z,int x,int y){
67 if(x>0){
68 return ((cs[z][y]-cs[z][x-1])%mod+mod)%mod;
69 }
70 return cs[z][y]%mod;
71 }
72
73 int main()
74 {
75 init();
76 int n,m,p,q;
77 int t;
78 cin>>t;
79 while(t--){
80 cin>>n>>m>>p>>q;
81 long long res =0;
82 for(int i=0;i<=n;i++){
83 for(int j=0;j<=m;j++){
84 if((n>=(i+2*j))&&(m>=(2*i+j))&&((p-2*(i+j))>=0)){
85 int tn = n-(i+2*j);
86 int tm = m-(2*i+j);
87 int tp = p-2*(i+j);
88 int tq = q;
89 long long ans = (cal(n,m,i)*cal(m-2*i,n-i,j))%mod;
90 for(int k=0;k<=tp+tq;k++){
91 if(k>min(tn,tm))
92 continue;
93 int maxp = min(k,tp);
94 int minp = max(0,k-tq);
95 long long tmp = ((solve(k,minp,maxp)*c[tn][k])%mod*c[tm][k])%mod;
96 tmp = (tmp*fac[k])%mod;
97 res = (res+tmp*ans)%mod;
98 }
99 }
100 }
101 }
102 res = ((res-1)%mod+mod)%mod;
103 cout<<res<<endl;
104 }
105 return 0;
106 }

hdu 4779 Tower Defense 2013杭州现场赛

时间: 2024-08-26 04:30:32

hdu 4779 Tower Defense 2013杭州现场赛的相关文章

hdu 4779 Tower Defense (思维+组合数学)

Tower Defense Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 474    Accepted Submission(s): 126 Problem Description DRD loves playing computer games, especially Tower Defense games. Tower De

hdu 4771 Stealing Harry Potter&#39;s Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: 目的:让你从 '@' 点出发,然后每个点只能走一次,求出最小的距离: 解题思路:先用 bfs 求解出任意两点之间的距离,用 ans[i][j],表示点 i 到点  j 的距离: 然后用 dfs 递归求出从起点经过所有点的距离中,比较出最小的: AC代码: 1 #include<iostream>

HDU 4821 杭州现场赛:每个片段字符串哈希比较

I - String Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4821 Description Given a string S and two integers L and M, we consider a substring of S as "recoverable" if and only if (i) I

HDU 4791 Alice&#39;s Print Service (2013长沙现场赛,二分)

Alice's Print Service Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1855    Accepted Submission(s): 454 Problem Description Alice is providing print service, while the pricing doesn't seem to

HDU 4815 2013长春现场赛C题

C - Little Tiger vs. Deep Monkey Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4815 Description A crowd of little animals is visiting a mysterious laboratory ? The Deep Lab of SYSU. "Are y

CUGBACM_Summer_Tranning3 2013长沙现场赛(二分+bfs模拟+DP+几何)

A题:二分 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4791 用lower_bound可以轻松解决,不过比赛的时候逗逼了. 刚开始没有预处理,所以队友给出一组数据的时候没通过,然后一时紧张又想不出什么好的解决办法,所以就没再继续敲代码.实在有点可惜了. #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #includ

hdu 4089 不错的DP 北京现场赛题

http://acm.hdu.edu.cn/showproblem.php?pid=4089 还有疑惑,需要重新推: 但是学到的: 1.A=a+b+c  abc是三种情况,那么P(A)=a*P(a->事件)+b*P(b->事件)+c*P(c->事件); a->事件意思是 在a情况下的事件,就是全概率公式的思想吧 2.一定注意每一步会不会出现分母为0 的情况,以及预处理的时候对于一些特殊情况导致自己的式子会出现分母为0的排除掉 3.概率DP经常出现推出了式子但是自己不会写代码的情况,

HDU 4793 Collision (2013长沙现场赛,简单计算几何)

Collision Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 685    Accepted Submission(s): 248Special Judge Problem Description There's a round medal fixed on an ideal smooth table, Fancy is tryin

hdu 4813(2013长春现场赛A题)

把一个字符串分成N个字符串 每个字符串长度为m Sample Input12 5 // n mklmbbileay Sample Outputklmbbileay 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <string> 6 # include <cmath> 7 # in