[HDU 4779 Tower Defense] 递推

题目

http://acm.hdu.edu.cn/showproblem.php?pid=4779

分析

重塔可以放成 ‘++’ 型, 轻塔和重塔都可以放成 ‘十’ 型。

用f[i][j][k]表示i*j的棋盘,没有空行空列,一共放了k个‘十’的方案数。这时 组成‘++’ 型的塔有(i+j)*2/3  因为一个‘++’占一行两列。

转移时考虑插入一个‘十’或一个‘++’  还有反过来的 ‘++’ 。规定必须有塔放在顶格,防止重复。

考虑顺推,将f[i][j][k]的值转给后面的状态

    f[i+1][j+1][k+1]+=1ll*(j+1)*f[i][j][k];
            f[i+1][j+2][k]+=1ll*c[j+2][2]*f[i][j][k];
            f[i+2][j+1][k]+=1ll*(i+1)*(j+1)*f[i][j][k];

然后这题必须加许多常数优化,比如f[i][j][k]=0则不转移,还有在循环时就将无效状态的上下界卡掉,。。。!!!

代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>

using namespace std;
typedef long long int64;
const int MOD=1000000007;
int f[210][210][210],ans,n,m,p,q,T;
int s[210][210],c[210][210];
inline void update(int &a,int64 b)
{
    a+=b;
    if(a>=MOD) a-=MOD;
}
int main()
{
    for(int i=0;i<=200;++i) c[i][0]=1;
    for(int i=1;i<=200;++i)
      for(int j=1;j<=i;++j)
        c[i][j]=c[i-1][j-1]+c[i-1][j],update(c[i][j],0);
    for(int i=0;i<=200;++i)
    {
        s[i][0]=1;
        for(int j=1;j<=i;++j)
          s[i][j]=s[i][j-1]+c[i][j],update(s[i][j],0);
    }
    f[0][0][0]=1;
    for(int i=0;i<=200;++i)
      for(int j=i/2;j<=200;++j)
        for(int k=0;k<=min(i,j);++k)
        {
            update(f[i+1][j+1][k+1],1ll*(j+1)*f[i][j][k]%MOD);
            update(f[i+1][j+2][k],1ll*c[j+2][2]*f[i][j][k]%MOD);
            update(f[i+2][j+1][k],1ll*(i+1)*(j+1)*f[i][j][k]%MOD);
        }
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d",&n,&m,&p,&q);
        ans=0;
        for(int i=1;i<=min(n,p+q);++i)
          for(int j=i/2;j<=min(m,p+q);++j)
          {
              for(int k=min(i,j)-abs(j-i)/2;k>=0;--k)
              {
                  if((i+j-2*k)%3) continue;
                  if((i+j-2*k)*2/3>p) break;
                  int a=(i+j-2*k)*2/3,b=k;
                  if(p-a<b-q) break;
                  if(!f[i][j][k]) continue;
                  update(ans,1ll*(s[b][min(b,p-a)]-((b-q-1)>=0?s[b][b-q-1]:0)+MOD)*c[n][i]%MOD*c[m][j]%MOD*f[i][j][k]%MOD);
              }
          }
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:([HDU 4779 Tower Defense] 递推)