Tower Defense

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 1025    Accepted Submission(s): 297

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
 
Recommend
We have carefully selected several similar problems for you:  6010 6009 6008 6007 6006 

分析:

因为重塔有两种放法...其中一种是和轻塔一样的,所以可以视为轻塔...

我们枚举有i行被两个棋子所占,j列被两个棋子所占...那么总占用行数为i+2*j,列数为j+2*i,使用重塔数为(i+j)*2,这个的方案数可以用组合数学搞定:c[n][i]*c[m][i<<1]*(i<<1)!/(2^i)...这是行的算法...列的算法是一样的...c[n][i]*c[m][i<<1]就不用说了...后面的就是我们已经从m列中选出了i*2列,现在我们把这些列分配给i行,第一行选择的方案数是c[i<<1][2],第二行的方案数是c[(i<<1)-2][2],第三行的方案数是c[(i<<1)-4][2]...最后一行的方案数是c[2][2]...化简一下就是(i<<1)!/(2^i)...

然后剩下的n-(i+2*j)行和m-(j+2*i)列中选出k行k列方轻塔和重塔,应该是c[n-(i+2*j)][k]*[m-(j+2*i)][k]*(重塔方案数)...

我们求出重塔的数量范围:Min=max(0,k-q),Max=min(k,p-2*(i+j))...所以重塔的方案数应该是c[k][Max]-c[k][Min-1]...

然后乘起来加一加就好了...

代码:

WA了好久...都是细节...

首先是2^i不能直接1LL<<i,而要预处理...因为i可能等于200...

然后阶乘要预处理到400...

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
#define int long long
using namespace std;
//眉眼如初,岁月如故 const int maxn=400+5,Mod=1e9+7; int n,m,p,q,cas;
long long ans,c[maxn][maxn],po[maxn],fac[maxn],sum[maxn][maxn]; inline long long power(long long x,int y){
long long res=1;
while(y){
if(y&1)
(res*=x)%=Mod;
(x*=x)%=Mod,y>>=1;
}
return res;
} signed main(void){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
scanf("%lld",&cas);c[0][0]=sum[0][0]=1;
for(int i=1;i<=400;i++)
c[i][0]=1,c[i][i]=1,sum[i][0]=1;
for(int i=1;i<=400;i++)
for(int j=1;j<i;j++)
c[i][j]=(c[i-1][j]+c[i-1][j-1])%Mod;
for(int i=1;i<=400;i++)
for(int j=1;j<=i;j++)
sum[i][j]=(sum[i][j-1]+c[i][j])%Mod;
fac[0]=1,po[0]=1;
for(int i=1;i<=400;i++)
fac[i]=fac[i-1]*i%Mod,po[i]=po[i-1]*2%Mod;
while(cas--){
scanf("%lld%lld%lld%lld",&n,&m,&p,&q);ans=0;
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
if(i+2*j<=n&&j+2*i<=m&&2*(i+j)<=p){
long long tmp=c[n][i]*c[m][2*i]%Mod*fac[i<<1]%Mod*power(po[i],Mod-2)%Mod;
(tmp*=c[m-i*2][j]*c[n-i][2*j]%Mod*fac[j<<1]%Mod*power(po[j],Mod-2)%Mod)%=Mod;
long long lala=0LL;
for(int k=0;k<=p-2*(i+j)+q;k++)
if(k<=n-(i+2*j)&&k<=m-(j+2*i)){
int Max=min(k,p-2*(i+j)),Min=max(0LL,k-q);
long long s;
if(Min==0LL)
s=0LL;
else
s=sum[k][Min-1];
(lala+=c[n-(i+2*j)][k]*c[m-(j+2*i)][k]%Mod*fac[k]%Mod*((sum[k][Max]-s+Mod)%Mod)%Mod)%=Mod;
}
(ans+=tmp*lala%Mod)%=Mod;
}
printf("%lld\n",(ans-1+Mod)%Mod);
}
return 0;
}//Cap ou pas cap. Pas cap.

  


By NeighThorn

HDU 4779:Tower Defense的更多相关文章

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

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

  2. HDU 4939 Stupid Tower Defense(dp)

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

  3. HDU 4939 Stupid Tower Defense (2014 Multi-University Training Contest 7)

    思路:首先红色肯定要放在最后面.前面蓝色和绿色dp求解. dp[i][j]  表示前面(i+j) 个 有 i 个蓝色塔  j个绿色塔 能造成最大伤害. //====================== ...

  4. 2014多校第七场1005 || HDU 4939 Stupid Tower Defense (DP)

    题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害 ...

  5. hdu 4939 Stupid Tower Defense ( dp )

    题目链接 题意:给出一条长为n个单位长度的直线,每通过一个单位长度需要t秒. 有3种塔,红塔可以在当前格子每秒造成x点伤害,绿塔可以在之后的格子每秒造成y点伤害, 蓝塔可以使通过单位长度的时间增加z秒 ...

  6. HDU 4939 Stupid Tower Defense

    dp:枚举red,dp前i 个塔中有j 个蓝塔的最大伤害. 机智的地方:dp前i 个塔的时候可以同时处理n-i 个红塔,这样就少了个循环...(枚举红塔的循环) #include <iostre ...

  7. HDU 4939 Stupid Tower Defense 简单DP

    题意: 地图为长为n个单位长度的直线,每通过一个单位长度需要t秒. 有3种塔,红塔可以在当前格子每秒造成x点伤害,绿塔可以在之后格子造成y点伤害,蓝塔可以使通过单位长度的时间增加z秒. 让你安排塔的排 ...

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

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

  9. hdu4939 Stupid Tower Defense (DP)

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

随机推荐

  1. Vue入门之v-if的使用

    在vue中一些常用的指令都是v-这样的,v-if是vue的一个内部指令,常用于html中 代码 <!DOCTYPE html> html lang="en"> & ...

  2. du 与df 统计系统磁盘不一致原因与解决方法

    事件起因: 同事发现云主机磁盘系统盘满了,准备清理系统盘,便利用du 命令统计了根目录下各文件夹的大小,发现统计的各文件夹的大小总和 加起来比 df 命令查看到的系统盘所使用空间 要小很多.这里记录下 ...

  3. B1020 月饼(25 分)

    B1020 月饼(25 分) 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意 ...

  4. Android开发——常见的内存泄漏以及解决方案(一)

    0. 前言   转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52333954 Android的内存泄漏是Android开发领域永恒的 ...

  5. 2 Model层-模型成员

    1 类的属性 objects:是Manager类型的对象,用于与数据库进行交互 当定义模型类时没有指定管理器,则Django会为模型类提供一个名为objects的管理器 支持明确指定模型类的管理器 c ...

  6. springboot(七):springboot+mybatis多数据源最简解决方案

    说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解 ...

  7. day19 Dgango进阶 路由系统及 ORM 详解

    完成一个完整的网页服务,需要有以下: 再次回顾一下Django 的完成开发流程: 一些值的获取: 对于性别,为互斥属性: 爱好则为多选: 需要使用新的方法 getlist 来获取多个爱好: 单选下拉框 ...

  8. loj2044 「CQOI2016」手机号码

    ref #include <iostream> #include <cstring> #include <cstdio> using namespace std; ...

  9. 配置网络策略中的 NAP 条件

    TechNet 库 Windows Server Windows Server 2008 R2 und Windows Server 2008 按类别提供的 Windows Server 内容 Win ...

  10. 接口测试之post和get的区别

    post和get都可以给服务器发送请求,在做接口测试的时候,我发现有些时候某些功能的接口文档中是用post请求发送的, 但是只要接口一致参数一致用post也能发送请求,并且获取到的返回也是正确的. 那 ...