BZOJ 4352 预处理 + DP
题目链接 : http://www.lydsy.com/JudgeOnline/problem.php?id=4352
一道SB题。。先把所有积木的长度从小到大排序。设前i块积木的摆放方案为f[i]。
先考虑第i块摆在最下面的情况。显然合法,且方案数为f[i-1]。
然后对于前i-1块的每一种摆放方案,都可以把第i块摆在s[i]块之上,其中s[i]为可以被第i块摆在上面的积木块数,可以O(n)预处理出来。
所以 f[i]=(s[i]+1)*f[i-1]
最终答案即为f[n]。
// BZOJ 4352 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=700000+5; #define rep(i,a,b) for (int i=a; i<=b; i++) #define read(x) scanf("%d", &x) int n, d, a[N], s[N]; long long ans; const int mod=998244353; int main() { read(n); read(d); rep(i,1,n) read(a[i]), s[i]=1; sort(a+1, a+n+1); int j=1, sum=0; rep(i,2,n) if (a[i]-a[j]<=d) { sum++; s[i]+=sum; } else { sum++; while (a[i]-a[j]>d && i>j) sum--, j++; s[i]+=sum; } ans=1; rep(i,1,n) ans=(ans*s[i])%mod; printf("%lld\n", ans); return 0; }