HDU 4779:Tower Defense
Tower Defense
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 1025 Accepted Submission(s): 297
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).
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)
2 2 0 1
2 2 2 0
3 3 2 1
10
144
分析:
因为重塔有两种放法...其中一种是和轻塔一样的,所以可以视为轻塔...
我们枚举有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的更多相关文章
- dp --- hdu 4939 : Stupid Tower Defense
Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- HDU 4939 Stupid Tower Defense(dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4939 解题报告:一条长度为n的线路,路上的每个单元格可以部署三种塔来给走在这条路上的敌人造成伤害,第一 ...
- HDU 4939 Stupid Tower Defense (2014 Multi-University Training Contest 7)
思路:首先红色肯定要放在最后面.前面蓝色和绿色dp求解. dp[i][j] 表示前面(i+j) 个 有 i 个蓝色塔 j个绿色塔 能造成最大伤害. //====================== ...
- 2014多校第七场1005 || HDU 4939 Stupid Tower Defense (DP)
题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害 ...
- hdu 4939 Stupid Tower Defense ( dp )
题目链接 题意:给出一条长为n个单位长度的直线,每通过一个单位长度需要t秒. 有3种塔,红塔可以在当前格子每秒造成x点伤害,绿塔可以在之后的格子每秒造成y点伤害, 蓝塔可以使通过单位长度的时间增加z秒 ...
- HDU 4939 Stupid Tower Defense
dp:枚举red,dp前i 个塔中有j 个蓝塔的最大伤害. 机智的地方:dp前i 个塔的时候可以同时处理n-i 个红塔,这样就少了个循环...(枚举红塔的循环) #include <iostre ...
- HDU 4939 Stupid Tower Defense 简单DP
题意: 地图为长为n个单位长度的直线,每通过一个单位长度需要t秒. 有3种塔,红塔可以在当前格子每秒造成x点伤害,绿塔可以在之后格子造成y点伤害,蓝塔可以使通过单位长度的时间增加z秒. 让你安排塔的排 ...
- hdu 4779 Tower Defense (思维+组合数学)
Tower Defense Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others) ...
- hdu4939 Stupid Tower Defense (DP)
2014多校7 第二水的题 4939 Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131 ...
随机推荐
- PAT 乙级 1024
题目 题目地址:PAT 乙级 1024 题解 模拟题,重点需要考虑到各种不同情况:简单来说一下: 因为输入格式固定,所以把不同的部分分别存储和处理可以在很大程度上简化运算:其中需要考虑最多的就是小数部 ...
- 【JAVA】mac配置java环境变量
如果用bash,修改~/.bash_profile 或 ~/.profile: 如果用zsh,修改-/.zshrc 修改这些文件之后,重修打开terminal,配置不会丢 首先确保已经安装了jdk: ...
- linux磁盘满了怎么办??删掉无用的大文件
今天公司网站突然无法访问,因为之前遇到过是因为磁盘问题,所以使用 df 命令查看结果,结果果然是有100%的东西,那么怎么解决呢,我们想到得查找大文件,并删掉无用的大文件比如log 那么linux如何 ...
- tcl之基本语法—3
- 迭代器Iterator与语法糖for-each
一.为什么需要迭代器 设计模式迭代器 迭代器作用于集合,是用来遍历集合元素的对象.迭代器迭代器不是Java独有的,大部分高级语言都提供了迭代器来遍历集合.实际上,迭代器是一种设计模式: 迭代器模式提供 ...
- Eclipse快速输出System.out.println();
借鉴网上大佬博客 刚开始还好好敲代码 后来看博客发现其实输入syso或sysout 再按alt+/就OK 开始学JAVA,好好干.
- Django基于Pycharm开发之三[命名空间 与过滤器]
关于命名空间的问题,在project项目中,我们可以设置路由类似于: from django.conf.urls import url,includefrom django.contrib impor ...
- cf982d Shark
ref #include <algorithm> #include <iostream> #include <cstdio> #include <map> ...
- Android资源限定符
Android系统会根据设备参数,自动选择最佳资源配置方案. Android中常见的资源限定符: 屏幕特征 限定符 描述 大小 small 提供给小屏幕设备的资源 normal 提供给中等屏幕设备的资 ...
- 创建 PSO
TechNet 库 Windows Server Windows Server 2008 R2 und Windows Server 2008 浏览 Windows Server 技术 Active ...