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. Homebrew-macOS缺失的软件包管理器(简称brew)

    [简介] brew又叫Homebrew,是Mac OSX上的软件包管理工具,能在Mac中方便的安装软件或者卸载软件,只需要一个简单的命令,非常方便 [遇到的问题] 在真正了解软件包管理工具之前,一直是 ...

  2. 每天进步一点点——关于SSD写入放大问题

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/29812433 1. 关于SSD的写入放大     之前在SSD(Solid State Dr ...

  3. asp.net core更进内容

    ASP.NET Core 是对 ASP.NET 的一次意义重大的重构.本文介绍了 ASP.NET Core 中的一些新概念,并且解释了它们如何帮助你开发现代的 Web 应用程序. 章节: 什么是 AS ...

  4. 仿LOL项目开发第四天

    ---恢复内容开始--- 仿LOL项目开发第四天 by草帽 上节讲了几乎所有的更新版本的逻辑,那么这节课我们来补充界面框架的搭建的讲解. 我们知道游戏中的每个界面都有自己的一个类型:比如登陆界面,创建 ...

  5. 一次SQL查询语句的优化

    1.项目中之前的"我关注的拍品列表"需要添加筛选功能,因为目前显示的关注的拍品太多没有进行分类,用户体验差. 2.添加筛选条件之后,可以筛选出“未开始”“进行中”“已结束”三种情况 ...

  6. LaTeX图片环境 Picture environment

    Picture environment If you need to include simple diagrams or figures in your document, the picture  ...

  7. ECMAScript新特性【一】--Object.create

    Object.create(prototype, descriptors) :创建一个具有指定原型且可选择性地包含指定属性的对象 参数: prototype 必需.  要用作原型的对象. 可以为 nu ...

  8. 在Spark中自定义Kryo序列化输入输出API(转)

    原文链接:在Spark中自定义Kryo序列化输入输出API 在Spark中内置支持两种系列化格式:(1).Java serialization:(2).Kryo serialization.在默认情况 ...

  9. go语言基础之闭包捕获外部变量特点

    1.闭包捕获外部变量特点 示例: package main //必须 import "fmt" func main() { a := 10 str := "mike&qu ...

  10. Sql Server参数化查询之where in和like实现之xml和DataTable传参 (转)

    在上一篇Sql Server参数化查询之where in和like实现详解中介绍了在Sql Server使用参数化查询where in的几种实现方案,遗漏了xml和表值参数,这里做一个补充 文章导读 ...