题目传送门
借鉴了:https://blog.csdn.net/weixin_44178736/article/details/106599966
思路:
f[i][j]表示将前 i 个人分成 j 组 ,我们先将数组从小到大排序,然后遍历数组
用pos来标记可以向左达到的最远处:a[i]-a[pos]<=5
则有状态转移方程: f[i][j] = max(f[i - 1][j], f[pos - 1][j-1]+i-pos+1)
前者表示没选第i个元素,后者表示选了第i个元素。
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
const int N = 5005;
int a[N];
int f[N][N];
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
int pos = 1;
for (int i = 1; i <= n; i++)
{
while (a[i]-a[pos]>5) pos++;
for (int j = 1; j <= k && j <= i; j++)
{
f[i][j] = max(f[i - 1][j], f[pos - 1][j-1]+i-pos+1);
}
}
int ans = 0;
for (int i = 1; i <= k; i++) ans = max(ans, f[n][i]);
cout << ans << endl;
return 0;
}✳
谢谢你读到这里。
更新于 2022-08-08