给你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. linux设置http/https proxy及忽略proxy的方法

    msys2设置网络代理 在文件 .bashrc 中添加 export http_proxy="proxy IP:port" 如 export http_proxy="19 ...

  2. Java获取字符串里面的重复字符

    public static void main(String[] args) { String word="天地玄黄宇宙洪荒" + "日月盈昃辰宿列张" + & ...

  3. 51nod 1135 原根 (数论)

    题目链接 建议与上一篇欧拉函数介绍结合食用. 知识点:1.阶:a和模m互质,使a^d≡1(mod m)成立的最小正整数d称为a对模m的阶(指数)   例如: 2^2≡1(mod3),2对模3的阶为2; ...

  4. Fortran学习记录3(选择语句)

    流程控制语句 if的基本用法 if-else语句块 多重判断if-elseif语句 if语句嵌套 Select case语句 Goto语句 PAUSE CONTINUE STOP 流程控制语句 if的 ...

  5. CF-1072-C. Cram Time(贪心,数学)

    CF-1072-C. Cram Time http://codeforces.com/contest/1072/problem/C 题意: 第一天有 a 小时,第二天有 b 小时.第 k 个任务需要 ...

  6. MySQL 资料库概论与MySQL 安装

    本文来自:https://www.breakyizhan.com/sql/5648.html 1. 储存与管理资料 储存与管理资料一直是资讯应用上最基本.也是最常见的技术.在还没有使用电脑来管理你的资 ...

  7. Windows Server 2008 R2+SQL Server 2014 R2升级到Windows Server 2016+SQL Server 2016

    环境: 操作系统:Windows Server 2008 R2 数据库:SQL Server 2014 因SQL Server 2016可以无域创建AlwaysOn集群,集群只剩下单节点也不会挂掉,故 ...

  8. url编码&&PHP大法&&这个看起来有点简单&&HTML 中有用的字符实体

    URL编码 Url编码通常也被称为百分号编码(Url Encoding,also known as percent-encoding),是因为它的编码方式非常简单,使用%百分号加上两位的字符——012 ...

  9. Java面试——从JVM角度比较equals和==的区别

    1.  Java中数据类型分类 1.1    基本数据类型 又称为原始数据类型,byte,short,char,int,long,float,double,boolean,他们之间的比较应该使用(== ...

  10. grunt与requirejs结合使用

    // 多个js压缩成一个js // Project configuration. module.exports = function(grunt) { // 使用严格模式 'use strict'; ...