显然是 DP 。这种贡献和最值有关的,一般用按顺序插入的方法 DP ,会简单很多。有挺多类似的题的。
这题就是 fi,j,k 表示插入了前 i 个,有
每次插入
有个问题就是一个块的贡献是延迟计算的,即闭合后才会确定贡献。 k 应该记什么呢?
比较直接的想法就是新开块时
所以我们应该假设当前的
总体来说比较套路吧。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=205,maxk=1005,MOD=1e9+7;
typedef long long LL;
int n,K,a[maxn];
LL f[2][maxn][maxk],ans;
int main(){freopen("cf626F.in","r",stdin);freopen("cf626F.out","w",stdout);scanf("%d%d",&n,&K);for(int i=1;i<=n;i++) scanf("%d",&a[i]);sort(a+1,a+1+n);f[0][0][0]=1; a[0]=a[1]; for(int i=0;i<=n-1;i++){memset(f[(i&1)^1],0,sizeof(f[(i&1)^1])); for(int j=0;j<=i;j++)for(int k=0;k<=K;k++) if(f[i&1][j][k]&&k+j*(a[i+1]-a[i])<=K){(f[(i&1)^1][j+1][k+j*(a[i+1]-a[i])]+=f[i&1][j][k])%=MOD; //新 (f[(i&1)^1][j][k+j*(a[i+1]-a[i])]+=f[i&1][j][k])%=MOD; //新 闭 if(j) (f[(i&1)^1][j][k+j*(a[i+1]-a[i])]+=f[i&1][j][k]*j%MOD)%=MOD; // 插入 if(j) (f[(i&1)^1][j-1][k+j*(a[i+1]-a[i])]+=f[i&1][j][k]*j%MOD)%=MOD; // 插入 闭 } }for(int i=0;i<=K;i++) ans=(ans+f[n&1][0][i])%MOD;printf("%lld\n",ans);return 0;
}