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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章