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
",dp[n+1][0]);
27     return 0;
28 }
View Code
原文地址:https://www.cnblogs.com/uuzlove/p/10467027.html