HDU4779 Tower Defense 组合数学

原文链接https://www.cnblogs.com/zhouzhendong/p/HDU4779.html

题目传送门 - HDU4779

题意

  $T$ 组数据。

  给定一个 $n\times m$ 的棋盘,要在上面放最多 $P$ 个重塔和最多 $Q$ 个轻塔。

  每一个塔都会攻击同行和同列的塔。轻塔不能承受任何攻击。重塔最多可以承受一个塔的攻击。

  所有重塔全是一样的,所有轻塔也是一样的,但是重塔和轻塔不同。

  现在问你有多少放置塔(至少放一个塔)的方案。答案对于 $1e9+7$ 取模。

  $1\leq T,n,m,P,Q\leq 200$

题解

  听说这一题 Cyanic 读错两次题意还出了一道毒瘤题给我们阿掉他的机会??

  我们写考虑枚举有两个重塔的行和列的个数。

  假设上面的两个量分别为 $i$ 和 $j$ 。

  则剩余行数和列数分别为 $n-i-2j$ 和 $m-2i-j$ ,剩余重塔个数为 $P-2i-2j$ 。

  我们可以预处理 $dp_{i}{j}$ 为在 $i$ 个行或列中选择 $j$ 对 行或列 的方案数。

  则显然答案为 $\binom{i}{2j}\ \ \ \ \ \ \ \ \times \ \ \ \ \ \ \ \ (2j)! \ \ \ \ \ \ \ \ ÷ \ \ \ \ \ \ \ \ 2^{j}$

  表示的意义: $i$ 行选 $2j$ 行    全排列     并依次选择每一对行或列     每一对行或列都有两种排列方式,总共被算了 $2^{j}$ 次,要除掉。

  然后枚举在剩余的 $n-i-2j$ 行和 $m-2i-j$ 列中放多少个塔。

  需要预处理一下组合数的前缀和。

  然后可以用组合数算出当前情况对答案的贡献。具体自己看代码吧。这里不展开赘述。

  注意一下,要特判掉不放塔的情况。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=405,mod=1e9+7;
int T,n,m,P,Q;
int C[N][N],Fac[N],Pow[N],s[N][N],dp[N][N];
int main(){
	Fac[0]=Pow[0]=1;
	for (int i=0;i<N;i++)
		C[i][0]=s[i][0]=1;
	for (int i=1;i<N;i++)
		Fac[i]=1LL*Fac[i-1]*i%mod,Pow[i]=1LL*Pow[i-1]*500000004%mod;
	for (int i=1;i<N;i++)
		for (int j=1;j<=i;j++){
			C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
			s[i][j]=(s[i][j-1]+C[i][j])%mod;
		}
	for (int i=0;i<N/2;i++)
		for (int j=0;j<N/2;j++)
			dp[i][j]=1LL*C[i][j*2]*Fac[2*j]%mod*Pow[j]%mod;
	scanf("%d",&T);
	while (T--){
		scanf("%d%d%d%d",&n,&m,&P,&Q);
		int ans=0;
		for (int r=0;r*2<=m;r++)
			for (int c=0;c*2<=n;c++){
				int RR=n-c*2-r,CC=m-r*2-c,p=P-r*2-c*2;
				if (RR<0||CC<0||p<0)
					continue;
				int mi=min(RR,CC),ma=max(RR,CC);
				int Mul=1LL*C[n-2*c][r]%mod*C[m-2*r][c]%mod*dp[m][r]%mod*dp[n][c]%mod;
				int tot=0,lim=min(mi,p+Q);
				for (int i=0;i<=lim;i++){
					int M2=s[i][min(p,i)];
					if (max(i-Q,0)-1>=0)
						M2=(M2-s[i][max(i-Q,0)-1]+mod)%mod;
					if (r||c||i)
						tot=(1LL*M2*C[ma][i]%mod*C[mi][i]%mod*Fac[i]+tot)%mod;
				}
				ans=(1LL*Mul*tot+ans)%mod;
			}
		printf("%d\n",ans);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/HDU4779.html

时间: 2024-08-30 17:58:29

HDU4779 Tower Defense 组合数学的相关文章

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

Stupid Tower Defense

题目链接 题意: 水平方向上n个1*1的格子,每个格子内部可以种一个植物,经过一个格子的时间为t.一共三种植物:R植物,经过时每秒收到r点伤害:G植物,经过后每秒受到g点伤害:B植物,经过后经过一个格子的时间加上b 2<=n<=1500,0<=r, g, b<=60000,1<=t<=3 分析: 最开始考虑的贪心:先B植物,后G植物,最后B植物,后来才发现是错误的. 首先明白,R植物对答案的影响和位置无关,而B和G植物越早种越好,所以问题就在于B和G的种法上. 状态表示

HDOJ题目4939 Stupid Tower Defense(dp)

Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1759    Accepted Submission(s): 498 Problem Description FSF is addicted to a stupid tower defense game. The goal of tower

HDU4939Stupid Tower Defense (有思想的dp)

Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1557 Accepted Submission(s): 445 Problem Description FSF is addicted to a stupid tower defense game. The goal of tower defen

hdu4939 Stupid Tower Defense(Dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4939 Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 493    Accepted Submission(s): 129 Problem Description FSF is addicte

HDOJ 4939 Stupid Tower Defense

red放到后面显然更优,dp[i][j]表示前i个塔里有j个blue,最后枚举有多少个red Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 599    Accepted Submission(s): 163 Problem Description FSF is addicted to

hdu 4939 Stupid Tower Defense

Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1589    Accepted Submission(s): 452 Problem Description FSF is addicted to a stupid tower defense game. The goal of tower

hdu 4939 Stupid Tower Defense ( dp )

题目链接 题意:给出一条长为n个单位长度的直线,每通过一个单位长度需要t秒. 有3种塔,红塔可以在当前格子每秒造成x点伤害,绿塔可以在之后的格子每秒造成y点伤害, 蓝塔可以使通过单位长度的时间增加z秒.问如何安排3种塔的顺序使得造成的伤害最大,输出最大伤害值. 分析:比赛的时候实在是没有想出来有三种不同的 塔,每种塔的作用不同,怎么dp.看题解才知道,应该把 所有的红塔放到最后面,因为直线的长度是一定的,而红塔在前面不会增加后面的伤害,然后问题就是如何安排 绿塔和蓝塔,我这里d[i][j]代表前

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

题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害. 蓝塔 : 经过该塔所在单位之后,再走每个单位长度的时候时间会变成t+z. 思路 : 官方题解 : 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define LL long long