codeforces 466D
题意:
给定n个数,你要选一些区间,每次区间+1,把这n个数都变成h
对任意两个区间,L1!=R1且L2!=R2
题解:
考虑每个位置只能不放,放一个区间左端点,放一个区间右端点,放一个左端点和一个右端点;
因此我们dp(i,j)表示到第i个,i和i+1之间被j个区间覆盖的方案数
讨论一下四种情况转移即可
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define maxn 2005 4 using namespace std; 5 const ll mod = 1000000007; 6 int n,h; 7 int a[maxn]; 8 ll dp[maxn][maxn]; 9 int main() 10 { 11 scanf("%d%d",&n,&h); 12 for(int i=1;i<=n;++i)scanf("%d",&a[i]),a[i]=h-a[i]; 13 for(int i=1;i<=n;++i)if(a[i]<0) 14 { 15 puts("0");exit(0); 16 } 17 a[0]=0; 18 dp[0][0]=1; 19 for(int i=0;i<=n;++i) 20 { 21 dp[i+1][a[i+1]]=(dp[i+1][a[i+1]]+dp[i][a[i+1]])%mod; 22 dp[i+1][a[i+1]-1]=(dp[i+1][a[i+1]-1]+dp[i][a[i+1]-1]*a[i+1])%mod; 23 dp[i+1][a[i+1]]=(dp[i+1][a[i+1]]+dp[i][a[i+1]-1])%mod; 24 dp[i+1][a[i+1]-1]=(dp[i+1][a[i+1]-1]+dp[i][a[i+1]]*a[i+1])%mod; 25 } 26 printf("%I64d\n",dp[n+1][0]); 27 return 0; 28 }