codeforces 1188 C. Array Beauty (dp)

题目链接:https://codeforces.com/contest/1188/problem/C?mobile=true

美丽值的最大值就是将最大的数平分到 ((k-1)) 个空位里,即 (frac{x}{k-1}),美丽值恰好为 (v) 的方案数不好算,考虑计算美丽值大于等于 (v) 的方案数

(dp[i][j]) 表示前 (i) 个数选了 (j) 个数的方案数,其中 (i) 必选,维护前缀和 (O(1)) 转移

时间复杂度为 (O(nk imes frac{x}{k-1}) = O(nx))

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1010;
const int M = 998244353;

int n, k;
int a[maxn], dp[maxn][maxn], sum[maxn][maxn], f[100010];

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	n = read(), k = read();
	int x = 0;
	for(int i = 1 ; i <= n ; ++i) a[i] = read(), x = max(x, a[i]); 
	a[0] = -1000000007;
	sort(a + 1, a + 1 + n);
	
	for(int v = 1 ; v * (k-1) <= x ; ++v){
		int pos = 0;
		dp[0][0] = 1;
		sum[0][0] = 1;
		for(int i = 1 ; i <= n ; ++i){
			while(a[i] - a[pos+1] >= v && pos+1 <= i-1) {
				++pos;
			}
			for(int j = 0 ; j <= k ; ++j){
				if(j) dp[i][j] = sum[pos][j-1];
				sum[i][j] = (sum[i-1][j] + dp[i][j]) % M;
			}
			f[v] = (f[v] + dp[i][k]) % M;
		}
	}
	
	for(int v = 1 ; v <= x / (k-1) ; ++v){
		f[v] = ((f[v] - f[v+1]) % M + M) % M;
	}
	
	int ans = 0;
	for(int v = 1 ; v <= x / (k-1) ; ++v){
		ans = (ans + 1ll * v * f[v] % M) % M;
	}
	
	printf("%d
", ans);
	
	return 0;
}
原文地址:https://www.cnblogs.com/tuchen/p/15177825.html