← 所有笔记

E. K Balanced Teams dp

E. K Balanced Teams dp

题目传送门
借鉴了: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

搜索笔记

搜索文章标题、标签和正文。

↑ ↓ 选择 · Enter 阅读Esc 关闭