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 Defense is a famous computer game with a number of variations. In general, you are to build some defense towers to guard your territory in this game.

  However, in most Tower Defense games, your defending towers will not attack each other. You will see the shells flying through your towers and finally hit the target on your screen. DRD thinks it to be absurd, and he designed a new tower defense game.

  In DRD’s game, you have two kinds of defending tower, heavy tower and light tower. You can put the tower on a grid with N rows and M columns and each cell in the grid can hold one tower at most. Both two kinds of towers can attack the cells in the same column
or the same row as it is located in, and your towers may attack each other. Moreover, light towers should not be attacked by other towers while heavy towers can be attacked by at most one other tower.

  You can put some of your towers (at least one tower) in the grid to build a tower formation satisfying the restriction above. And now, DRD wants you to calculate that how many different tower formations could be designed. Note that all the towers of the same
type are considered to be identical. While the answer could be quite large, you should output the number mod (109 + 7).
 
Input
  There are multiple test cases in the input. The first line of the input file is an integer T demonstrating the number of test cases. (0< T<= 200).

  For each test case, there is only one line containing 4 integers, N, M, P and Q ,meaning that the grid has N rows and M columns, and you have P heavy towers and Q light towers. You do not have to put all the towers in the grid. (1 <= N, M <= 200, 0 <= P,
Q <= 200)
 
Output
  For each test case, output the number of different formations mod (109 + 7) in a single line.
 
Sample Input
3
2 2 0 1
2 2 2 0
3 3 2 1
 
Sample Output
4
10
144
 
Source


思路来源于:点击打开链接

题意:
有两种塔,重塔,轻塔。

每种塔,能攻击他所在的一行和他所在的一列, 轻塔不 能被攻击。而重塔能够被至多一个塔攻击,也就是说重塔仅仅能被重塔攻击。

在一个n*m 的矩阵中,最少放一个塔,可放多个。

问。给定p个重塔,q个轻塔。问有多少种放法。


思路:
1、 一行中有两个重塔,

2、 一列中有两个重塔

3、 在该行及在该行塔所在的列仅仅有一个塔,重塔或者轻塔。

对以上三种情况挨个处理:

1、 设有i行有两个重塔,j列有两个重塔,则一共占 i+2*j 行, j+2*i列,共用2*(i+j)个重塔,,由于一行或一列两个塔

2、 对剩余的塔,进行枚举,0<-->剩余的塔。枚举这些塔中重塔的个数进行枚举


对于1: 在行中有两个重塔 c(n,i)*c(m,2*i)*((2*i)!/2^i)   意思 是在n行中选i行,在m列中选2*i列,  对于选出来的2*i列,分成i组。须要进行全排列,可是组内不须要进行全排列。所以为(2*i)!/2^i 在列中有两个重塔,c(m-2*i,j)*c(n-i,2*j)*((2*j)!/2^j)  原理同上



对于2:设有k个塔, 在剩余的n-(i+2*j) 行  m-(2*i+j) 列中 选 k个 点 (现有的行列组合*k!),k最大为  p-2*(i+j)+q,对于k个塔,则重塔最多有b =  min (k, p-2*(i+j) ) 个,  最少有a =  max(0,k-q) 个 。k个塔,最少 a 。最多b  则为重塔的取法有(c[k][0]+c[k][1]...+c[k][b])- (c[k][0]+c[k][1]+...+c[k][a-1]);

最后将不放的情况减掉就可以,也就是减1;

代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 405
#define MAXN 200005
#define INF 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
const double pi=acos(-1.0);
typedef long long ll;
using namespace std; ll n,m,ans,cnt,p,q;
ll c[maxn][maxn],sum[maxn][maxn],fac[maxn],odd[maxn]; void presolve()
{
ll i,j;
for(i=0;i<=200;i++) c[i][0]=sum[i][0]=1;
for(i=1;i<=200;i++)
{
for(j=1;j<=i;j++)
{
c[i][j]=c[i-1][j]+c[i-1][j-1];
c[i][j]%=mod;
}
}
for(i=0;i<=200;i++)
{
for(j=1;j<=200;j++)
{
sum[i][j]=sum[i][j-1]+c[i][j];
sum[i][j]%=mod;
}
}
fac[0]=odd[1]=1;
for(i=1;i<=400;i++)
{
fac[i]=(fac[i-1]*i)%mod;
if(i>1&&(i&1)) odd[i]=(odd[i-2]*i)%mod;
}
}
void solve()
{
ll i,j,t,k;
ans=0;
for(i=0; i<=n; i++)
{
for(j=0; j<=m; j++)
{
if(i+2*j>n||(j+2*i)>m||2*(i+j)>p) break ;
if(2*i-1>0) t=odd[2*i-1];
else t=1;
ll res=(((((c[n][i]*c[m][2*i])%mod)*t)%mod)*fac[i])%mod;
if(2*j-1>0) t=odd[2*j-1];
else t=1;
res=((((res*c[m-2*i][j])%mod*c[n-i][2*j])%mod*t)%mod*fac[j])%mod; ll tp=p-2*(i+j),tq=q,tn=n-(i+2*j),tm=m-(j+2*i);
for(k=0;k<=tp+tq;k++)
{
if(k>tn||k>tm) break ;
ll minp=max(0LL,k-tq),maxp=min(k,tp);
if(minp==0) t=0;
else t=sum[k][minp-1];
ll tmp=((((c[tn][k]*c[tm][k])%mod*fac[k])%mod)*(sum[k][maxp]-t))%mod;
ans=(ans+tmp*res)%mod;
}
}
}
ans=(ans-1+mod)%mod;
printf("%lld\n",ans);
}
int main()
{
ll i,j,t;
presolve();
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld%lld%lld",&n,&m,&p,&q);
solve();
}
return 0;
}
/*
3
2 2 0 1
2 2 2 0
3 3 2 1
*/

 

hdu 4779 Tower Defense (思维+组合数学)的更多相关文章

  1. hdu 4779 Tower Defense 2013杭州现场赛

    /** 题意: 有两种塔,重塔,轻塔.每种塔,能攻击他所在的一行和他所在的一列, 轻塔不 能被攻击,而重塔可以被至多一个塔攻击,也就是说重塔只能被重塔攻击.在一个n*m 的矩阵中,最少放一个塔,可放多 ...

  2. HDU 4779:Tower Defense

    Tower Defense Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)T ...

  3. dp --- hdu 4939 : Stupid Tower Defense

    Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  4. hdu4939 Stupid Tower Defense (DP)

    2014多校7 第二水的题 4939 Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131 ...

  5. Stupid Tower Defense

    Problem Description FSF is addicted to a stupid tower defense game. The goal of tower defense games ...

  6. 初识Tower Defense Toolkit

    Tower Defense Toolkit 做塔防游戏的插件 主要层次如下图: 1GameControl _ _Game Control(Script) _ _ _Spawn Manager _ _ ...

  7. HDU4939Stupid Tower Defense (有思想的dp)

    Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Oth ...

  8. Tower Defense Game

    Tower Defense Game 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 There is a tower defense game with n level ...

  9. HDU 4939 Stupid Tower Defense(dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4939 解题报告:一条长度为n的线路,路上的每个单元格可以部署三种塔来给走在这条路上的敌人造成伤害,第一 ...

随机推荐

  1. linux查看某个端口是被哪个进程占用的

    查看某个端口是被哪个进程占用的: netstat -tunpl | grep 6379

  2. JavaScript程序员必备的5个debug技巧

    1. debugger:我以前也说过,你可以在JavaScript代码中加入一句debugger;来手工造成一个断点效果.需要带有条件的断点吗?你只需要用if语句包围它: if (somethingH ...

  3. iOS开发 贝塞尔曲线UIBezierPath(2)

    使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形 . 1:UIBezierPath: UIBezierPath是在 UIKit 中 ...

  4. sqlserver锁大全

    锁定提示                                 描述  HOLDLOCK        将共享锁保留到事务完成,而不是在相应的表.行或数据页不再需要时就立即释放锁.HOLDL ...

  5. Perl &amp; Python编写CGI

    近期偶然玩了一下CGI,收集点资料写篇在这里留档. 如今想做HTTP Cache回归測试了,为了模拟不同的响应头及数据大小.就须要一个CGI按须要传回指定的响应头和内容.这是从老外的測试页面学习到的经 ...

  6. pidera安装node.js(树莓派)

    1. 下载node.js wget http://nodejs.org/dist/v0.10.5/node-v0.10.5-linux-arm-pi.tar.gz tar -xzvf node-v0. ...

  7. SQL Alias

    There are two types of aliases that are used most frequently in SQL command: which is column alias a ...

  8. 【Networking】Libevent客户端例子

    [原]Libevent客户端例子 时间 -- :: luotuo44的专栏 原文 http://blog.csdn.net/luotuo44/article/details/34416429 主题 l ...

  9. 【云计算】Docker容器不能修改hosts文件怎么解决?

    参考资料: http://bbs.csdn.net/topics/390871429 http://tieba.baidu.com/p/4295556808 http://stackoverflow. ...

  10. 使用Intellij加载Spark源代码

    如何使用Intellij加载Spark源代码 转载注明原文http://www.cnblogs.com/shenh062326/p/6189643.html 查看Spark源代码或修改Spark源代码 ...