链接
知识点
动态规划
思路
表示前
条街道,总共建造
个房屋的方案数,先枚举每条街道,在枚举当前街道,能建造的房屋数,再枚举前
条街道,能建造的房屋数,当前街道建
个房屋,前
条街道总共建
个房屋,故前i条街道共建
个房屋,用
表示方案数,
累加上 在前
个街道上建
个房屋的方案数,即
。
动态转移方程为 %
代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll mod = 1e9 + 7;
ll dp[55][2605]; //dp[i][j]表示只考虑前i条街道,总共建造j个房屋的方案数
int main()
{
int n,m,k;
cin >> n >> m >> k;
for(int i = 0; i <= k; i++) dp[0][i] = 1; //初始化,便于后续递推
for(int i = 1; i <= n; i++)//依次考虑前1~n条街道
{
for(int j = 1; j <= m ; j++)//考虑依次在当前街道(第i条街道)建造1~m个房屋
{
for(int s = i-1; s <= k-1; s++)
//对于前i-1条街道,首先每条街道至少建一个房屋,总共至少建i-1个房屋,至多建k-1个房屋
//故从i-1遍历到k-1,即为前i-1条街道所有可能的房屋总数
{
//当前街道建j个房屋,前i-1条街道总共建s个房屋,故前i条街道共建j+s个房屋,用dp[i][j+s]表示方案数
//dp[i][j+s] 累加上 在前i-1个街道上建s个房屋的方案数,即dp[i-1][s]
dp[i][j+s] = (dp[i][j+s] + dp[i-1][s]) % mod;
}
}
}
cout << dp[n][k] << endl; //dp[n][k]即在前n条街道,总共建造k个房屋的方案数
return 0;
}