给你p个重塔,q个轻塔,把这些塔放在n*m的图中,这些塔会相互攻击同行同列的,轻塔不能受到攻击,重塔能承受一个塔的攻击,

问放的方法数。

先假定n < m。

可以先枚举放轻塔的个数为s,显然,方法数为C(n,s) * m * (m-1) * ... * (m-s+1) ,放完之后我们可以发现图其实缩小成为了一个(n-s)*(m-s)的图。

然后放重塔,由于重塔可以承受一个塔的攻击,dp求一下方案,令dp(i,j,k) 表示i*j的图中放k个重塔的方法,通过在图的第一行进行限定条件枚举。

可分为3个小部分:

1.第一行不放重塔 dp(i,j,k) += dp(i-1,j,k)

2.第一行放一个重塔,又分两种情况:

A:同一列不放重塔 dp(i,j,k) += j*dp(i-1,j-1,k-1)

B:同一列放重塔 dp(i,j,k) += j*(i-1)*dp(i-2,j-1,k-2)

3.第一行放两个重塔

dp(i,j,k) += C(j,2)*dp(i-1,j-2,k-2)

求出dp数组之后即总方法数为segma(0,q,i) segma(0,p,j) C(n,i)*m*...*(m-i+1)*dp(n-i,m-i,j)

由于不能不放,所以需要最后减去1.

时间复杂度为K*200^3,K为一常数。

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
#include <functional>
#include <stack>
#include <bitset>
using namespace std;
typedef long long ll;
#define INF (0x3f3f3f3f)
#define maxn (1000005)
#define mod 1000000007
#define ull unsigned long long
ll C[][],dp[][][];
void init(){
for(int i = ;i <= ;++i) C[i][] = ;
for(int i = ;i <= ;++i){
for(int j = ;j <= i;++j){
C[i][j] = C[i-][j] + C[i-][j-];
if(C[i][j] >= mod) C[i][j] %= mod;
}
}
for(int i = ;i <= ;++i) for(int j = ;j <= ;++j) dp[i][j][] = ;
for(int i = ;i <= ;++i){
for(int j = ;j <= ;++j){
for(int k = ;k <= ;++k){
//第一行不取
if(i == && j == ){
int t = ;
}
dp[i][j][k] += dp[i-][j][k];
//第一行取一个
dp[i][j][k] += j * dp[i-][j-][k-]%mod;//对应的列不取
if(dp[i][j][k] >= mod) dp[i][j][k] %= mod;
if(i >= && k >= ) dp[i][j][k] += j * (i-) * dp[i-][j-][k-]%mod;//对应的列取
if(dp[i][j][k] >= mod) dp[i][j][k] %= mod;
//第一行取两个
if(j >= && k >= ) dp[i][j][k] += C[j][]*dp[i-][j-][k-]%mod;
if(dp[i][j][k] >= mod) dp[i][j][k] %= mod;
}
}
}
}
ll quickpow(ll x,ll y){
ll ans = ;
while(y){
if(y & ){
ans = ans * x;
if(ans >= mod) ans %= mod;
}
x *= x;
if(x >= mod) x %= mod;
y >>= ;
}
return ans;
}
int main()
{
int T;
int n,m,p,q;
init();
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d",&n,&m,&p,&q);
if(n > m) swap(n,m);
int li = min(q,n);
ll s = ,ans = ;
for(int i = ;i <= li;++i){
for(int j = ;j <= p;++j){
ans = ans + C[n][i] * s % mod * dp[(n-i)][(m-i)][j] % mod;
if(ans >= mod) ans %= mod;
}
s = s * (m - i);
if(s >= mod) s %= mod;
}
--ans;
if(ans < ) ans += mod;
printf("%lld\n",ans);
}
return ;
}

I.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. hdu4939 Stupid Tower Defense (DP)

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

  3. Stupid Tower Defense

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

  4. 初识Tower Defense Toolkit

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

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

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

  6. Tower Defense Game

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

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

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

  8. HDU 4779:Tower Defense

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

  9. hihoCoder #1199 : Tower Defense Game ——(树型dp)

    题目链接:https://hihocoder.com/problemset/problem/1199. 题意:一棵以1为根的树,每个点有一个p值和q值,到这个点需要当前分数大于等于p,然后消耗掉(p- ...

  10. HDU 4939 Stupid Tower Defense(dp)

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

随机推荐

  1. C++ _ const的用法,特别是用在函数前面与后面的区别!

    在普通的非 const成员函数中 this的类型是一个指向类类型的 const指针.可以改变this所指向的值,但不能改变 this所保存的地址. 在 const成员函数中 this的类型是一个指向 ...

  2. 国庆集训 || Wannafly Day4

    链接:https://www.nowcoder.com/acm/contest/205#question 一场题面非常 有趣 但是题目非常 不友好的比赛 QAQ L.数论之神   思维(?) 题意:求 ...

  3. SSI的实例(登录增删改查)

    源码下载:http://download.csdn.net/detail/u011518709/8195143 主要jar包: 配置文件:web.xml <?xml version=" ...

  4. 基于Passthru的NDIS开发的个人理解

    这几天对NDIS的学习,基本思路是:首先熟悉理论知识→然后下载一个例子进行研究→最后例子自己模仿扩展→最最后尝试自己写一个新的. Passthru是微软NDIS自己写的一个框架驱动,NDIS开发者可以 ...

  5. mycat中间件安装与使用

    前提: 安装JDK版本在7.0及其以上 1.下载: 下载地址在:http://dl.mycat.io/ 选择1.6-release版本下载 2.安装: 直接解压即可: tar -zxf Mycat-s ...

  6. sudo指令和/etc/sudoers文件说明

    sudo 命令 -l 显示当前用户的sudo权限-l username 显示username的sudo权限-u username 以username的权限执行-k 强迫用户下一次执行sudo时问密码( ...

  7. free指令的说明

    CentOS 6.x系统中的freefree [-b|-k|-m|-g|-h] [-l] [-o] [-t] [-s delay] [-c count] [-V] -b #-k,-m,-g 以单位by ...

  8. 命令行发送UDP

    https://www.cnblogs.com/Dennis-mi/articles/6866762.html: 如果往本地UDP端口發送數據,那麼可以使用以下命令:echo “hello” > ...

  9. python中split()函数讲解

    本文讲述的是string.split(s[, sep[, maxsplit]]),针对string类型的split()函数.它主要是切割字符串,结果返回由字符串元素组成的一个列表,具体怎么使用看下面的 ...

  10. PAT Basic 1015

    1015 德才论 宋代史学家司马光在<资治通鉴>中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人.凡取人之术,苟不得圣人,君子而与之,与其 ...