soj#551 loj#2833 帐篷

传送门

分析

dp[i][j]表示考虑了i行j列的方案数

我们每次考虑三种情况:

  一个点自己放

  两个点在同一行

  两个点在同一列

代码

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
#define add(x,y) x=(x+y)%mod
int dp[3010][3010],n,m;
int main(){
    int i,j,k;
    scanf("%d%d",&n,&m);
    dp[0][0]=1;
    for(i=1;i<=n;i++)dp[i][0]=1;
    for(i=1;i<=m;i++)dp[0][i]=1;
    for(i=1;i<=n;i++)
      for(j=1;j<=m;j++){
          add(dp[i][j],dp[i-1][j]);
          add(dp[i][j],4ll*j*dp[i-1][j-1]%mod);
          if(i>1)add(dp[i][j],1ll*j*(i-1)%mod*dp[i-2][j-1]%mod);
          if(j>1)add(dp[i][j],1ll*j*(j-1)/2%mod*dp[i-1][j-2]%mod);
      }
    cout<<dp[n][m]-1<<"\n";
    return 0;
}
posted @ 2019-07-26 06:52  水题收割者  阅读(81)  评论(0编辑  收藏  举报