//状态转移方程有两种 1:如果这种花已经选择过了,那么还要选择这种花的话,就只需要继承这朵花上一次被选择的方案。因为这朵花只能放在上一朵同样的花之后。 dp[i][j][z]=dp[i][j-1][z-1] 2:如果这种花没有被选择过,那么就要加上这种花之前所有能放满z-1位的方案数。 dp[i][j][z]=dp[a][b][z-1]; (a是这种花之前的花的种类,只要是能填满z-1朵花,就符合要求,并加上其方案数) (我是小菜鸡,题解写的也不是很清晰易懂,体谅体谅) 代码如下:
#include<iostream>
using namespace std;
#define int long long
const int mode=1000007;
int m,n;
int arr[110];
int dp[110][110][110];//第几种花,这种花的第几个,放在第几个位置上
int sum=0;
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>arr[i];
for(int i=1;i<=n;i++)
{
dp[i][0][0]=1;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=arr[i];j++)
{
for(int z=1;z<=m;z++)
{
dp[i][j][z]=dp[i][j-1][z-1]%mode;
if(j!=1)
continue;
for(int a=1;a<i;a++)
{
for(int b=1;b<=arr[a];b++)
dp[i][j][z]+=dp[a][b][z-1]%mode;
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=arr[i];j++)
sum+=dp[i][j][m];
sum=sum%mode;
}
cout<<sum;
return 0;
}