题意:选择若干个不重复的区间执行+1操作,求有多少种方法使得序列都是
莫名的感觉此题出的好。第一次发现可以用dp计算非常复杂的方案数,而且方案看视非常复杂。
貌似该题有多种解法:copyhttp://blog.youkuaiyun.com/rowanhaoa/article/details/39343525
http://blog.youkuaiyun.com/u011345136/article/details/39315889
思路:DP[i][j]表示到第i个位置,前面还有j个点未被选(不包括i)
1. a[i]+j==h 表示可以从前面j个点中任意选一个点与i匹配或者不选
2. a[i]+j+1==h 表示可以从前面j个点以及i中任意选一个点i匹配或者不选
我们这样可以把一种方案的步骤细分,分成每一个状态。
我们这样可以把一种方案的步骤细分,分成每一个状态。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int M= 1e9+7;
int a[2010];
int d[2010][2010];
int m,n;
int dfs(int cur,long long left)
{
if(d[cur][left])
return d[cur][left];
if(cur==n)
{
if(left==0)
return d[cur][left]=1;
return d[cur][left]=0;
}
if(left==m-a[cur]) {
return d[cur][left]=((left*dfs(cur+1,left-1)%M)+dfs(cur+1,left))%M;
}
else if(left+1==m-a[cur])
{
return d[cur][left]=(((left+1)*dfs(cur+1,left)%M)+dfs(cur+1,left+1))%M;
}
return 0;
}
int main()
{
int i,j,k;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(d,0,sizeof(d));
for(i=0;i<n;i++)
scanf("%d",&a[i]);
printf("%d\n",dfs(0,0));
}
}