4418. 选元素(动态规划)

简介: 笔记

题面


1.png

思路


2.png

代码


#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 210;
#define int long long
int f[N][N];
int n, k, m;
signed main()
{
    cin >> n >> k >> m;
    memset(f, -0x3f, sizeof f);
    f[0][0] = 0;
    for (int i = 1; i <= n; i++) {
        int x; cin >> x;
        for (int j = 1; j <= m; j++) 
            for (int z = max(i - k, 0ll); z < i; z++)
                f[i][j] = max(f[i][j], f[z][j - 1] + x);
    }
    int res = -1;
    for (int i = n - k + 1; i <= n; i++) 
        res = max(res, f[i][m]);
    cout << res << endl;
    return 0;
}

单调队列优化

  • 之后再补一下这个做法,理解不透彻,遇到好几次这种题啦。
// 单调队列优化
#include <bits/stdc++.h>
using namespace std;
const int N=210;
typedef long long LL;
LL f[N][N];
int a[N];
int q[N];
int hh=0,tt=-1;
int n,k,x;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>k>>x;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        LL q = a[i];
    }
    //f[i][j]表示当前已经选择了i个点,且最后一个点的位置是j的所有集合,属性max
    memset(f,-0x3f,sizeof(f));
    f[0][0]=0;
    for(int i=1;i<=x;i++){
        int hh=0,tt=-1;
        for(int j=0;j<=n;j++){
            if(hh<=tt && q[hh] + k < j ) hh++;
            if(hh<=tt) f[i][j] = f[i-1][q[hh]] + a[j];
            while(hh<=tt && f[i-1][q[tt]] <= f[i-1][j]) tt--;
            q[++tt] = j;
        }
    }
    LL res = -1;
    for(int i=n-k+1;i<=n;i++) res = max(res, f[x][i]);
    cout<<res<<endl;
    return 0;
}
相关文章
|
4天前
|
算法 测试技术 C++
【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组
【动态规划】【滑动窗口】【C++算法】 629K 个逆序对数组
|
4天前
|
移动开发 算法 测试技术
【动态规划】【记忆化搜索】C++算法:546移除盒子
【动态规划】【记忆化搜索】C++算法:546移除盒子
|
4天前
|
人工智能 算法 测试技术
map|动态规划|单调栈|LeetCode975:奇偶跳
map|动态规划|单调栈|LeetCode975:奇偶跳
|
4天前
|
缓存 算法 测试技术
【单调栈】【二分查找】LeetCode: 2454.下一个更大元素 IV
【单调栈】【二分查找】LeetCode: 2454.下一个更大元素 IV
|
4天前
|
算法
算法题解-多数元素2
算法题解-多数元素2
|
4天前
|
算法 索引
算法题解-数组中的第K个最大元素
算法题解-数组中的第K个最大元素
|
7月前
|
存储 算法 索引
3.数组算法、动态规划
3.数组算法、动态规划
|
11月前
|
算法
子序列动态规划编程题集合(leetcode)
子序列动态规划编程题集合(leetcode)