Problem A 蛋糕
将$n \times m $大小的蛋糕切成每块为$1 \times 1$大小的$n\times m$块。
交换任意两块蛋糕的切割顺序的方案算作一种。
对于$100 \%$的数据满足$1 \leq n,m \leq 300$
Solution : 一个比较明显的DP
设$f[i][j]$表示蛋糕大小为$i \times j$时候的答案。
当前步可以在第$k(1\leq k \leq i-1)$行切一刀分成$[1,k]$和$[k+1,i]$两部分;
或者可以在第$k(q\leq k \leq j-1)$列切一刀分成$[1,k]$和$[k+1,j]$ 两部分。
问题就可以转化为两个子问题了(由乘法原理可以合并),然后把所有子问题相加就是最后的答案。
枚举状态是$O(n^2)$,然后枚举转移是$O(n)$的复杂度,总复杂度是$O(n^3)$
# include<bits/stdc++.h> # define int long long using namespace std; const int N=305,mo=1e9+7; int f[N][N]; int dfs(int i,int j) { if (i==1 && j==1) return 1; if (i<0 || j<0) return 0; if (f[i][j]!=-1) return f[i][j]; int ret=0; for (int k=1;k<=i-1;k++) ret=(ret+dfs(k,j)*dfs(i-k,j)%mo)%mo; for (int k=1;k<=j-1;k++) ret=(ret+dfs(i,k)*dfs(i,j-k)%mo)%mo; return f[i][j]=ret; } signed main() { int n,m; scanf("%lld%lld",&n,&m); memset(f,-1,sizeof(f)); printf("%lld\n",dfs(n,m)); return 0; }