給出 n 個數,選取其中若干個數分別組成至多 k 組,要求每組內最大值與最小值的差值不超過5,求最後被選上的總人數。html
將a[1∼n] 從小到大排序,ios
f[i][j] 表示到第 i 個數爲止,已經組成 j 組,最多能夠包含多少個數。數組
那麼,考慮第 i 個數選取與否,若是不選,那麼 , spa
若是選,那麼必然是第 i 個數所在組人數加上前面那些組人數,假設 p 表示距離 a[i]左側最遠的那個位置(知足 ),這裏是指p以前的那些組的人數.net
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int n, k; const int maxn = 5000 + 10; int a[maxn]; int f[maxn][maxn]; int main() { cin >> n >> k; for(int i = 1; i <= n; i++) cin >> a[i]; sort(a+1, a + n + 1); int p = 1; int ans = 1; memset(f, 0, sizeof(f)); f[1][1] = 1; for(int i = 2; i <= n; i++) { while(p < i && a[i] - a[p] > 5) // p~i爲一組 p++; for(int j = 1; j <= min(k, i); j++) //i可能小於k,也可能大於k(這時就應限制大小) { f[i][j] = max(f[i-1][j], (i - p + 1) + f[p-1][j-1]); ans = max(ans, f[i][j]); } } cout << ans << endl; }
注:發現從數組從下標1開始輸入比較穩妥,能夠避免樣例1發生p-1=-1的狀況blog