《CF833B The Bakery》

题目描述

不久前,Slastyona the Sweetmaid 决定开设自己的面包店!她买齐了所需的原料,还有一台可以烘焙多种蛋糕的奇妙烤箱,并开张了面包店。

很快,开支开始超过收入,于是 Slastyona 决定研究甜点市场。她了解到,将蛋糕装入盒子会更有利可图,而且每个盒子里不同种类蛋糕越多(我们将这个数量称为盒子的价值),价格就越高。

她需要改变生产技术!问题在于,烤箱会自行决定蛋糕的种类,Slastyona 无法干预。然而,她知道今天烤箱将要依次烘烤出 n 个蛋糕的类型和顺序。今天,Slastyona 必须准确地用 k 个盒子来打包这些蛋糕,并且每个盒子内必须放入若干(至少一个)连续烘焙出来的蛋糕(换句话说,每个盒子包含一段蛋糕的连续区间)。

Slastyona 希望最大化所有盒子的总价值。请你帮她求出所有盒子的最大可能总价值。

输入格式

第一行包含两个整数 n 和 k(1≤n≤35000,1≤k≤min(n,50))------蛋糕的数量以及盒子的数量。

第二行包含 n 个整数 a1​,a2​,...,an​(1≤ai​≤n)------按照烤箱生产顺序排列的蛋糕类型。

输出格式

输出唯一一个整数,表示所有盒子中的蛋糕最大可能的总价值。

显示翻译

题意翻译

输入输出样例

输入 #1复制

复制代码
4 1
1 2 2 1

输出 #1复制

复制代码
2

输入 #2复制

复制代码
7 2
1 3 3 1 4 4 4

输出 #2复制

复制代码
5

输入 #3复制

复制代码
8 3
7 7 8 7 7 8 1 7

输出 #3复制

复制代码
6

说明/提示

在第一个样例中,Slastyona 只有一个盒子。她必须把所有蛋糕都放进这个盒子里,因此这个盒子有两种类型,价值为 2。

在第二个样例中,最优策略是将前两个蛋糕放入第一个盒子,其余的都放进第二个盒子。则第一个盒子有两种类型,第二个盒子有三种类型,因此总价值为 5。

由 ChatGPT 5 翻译

代码实现;

cpp 复制代码
#include<bits/stdc++.h>
#define re register
#define il inline
using namespace std;

const int N=35005;
const int M=55;

int n,k;
int a[N];
int dp[N][M];
int pre[N], pos[N];
int vis[N], p[N];

struct SegTree{
    struct nd{
        int l,r,v,ad;
    }t[4*N];
    
    void pd(int p){
        if(t[p].ad){
            int lc=p<<1, rc=p<<1|1;
            t[lc].v += t[p].ad;
            t[rc].v += t[p].ad;
            t[lc].ad += t[p].ad;
            t[rc].ad += t[p].ad;
            t[p].ad = 0;
        }
    }
    
    void clr(int i, int p, int l, int r){
        t[p].l=l, t[p].r=r;
        if(l==r){
            t[p].v = dp[l][i];
            return ;
        }
        int m=(l+r)>>1;
        clr(i, p<<1, l, m);
        clr(i, p<<1|1, m+1, r);
        t[p].v = max(t[p<<1].v, t[p<<1|1].v);
    }
    
    void upd(int p, int l, int r, int x){
        if(t[p].l>=l && t[p].r<=r){
            t[p].ad += x;
            t[p].v += x;
            return ;
        }
        pd(p);
        int m=(t[p].l + t[p].r)>>1;
        if(l<=m) upd(p<<1, l, r, x);
        if(r>m) upd(p<<1|1, l, r, x);
        t[p].v = max(t[p<<1].v, t[p<<1|1].v);
    }
    
    int qry(int p, int l, int r){
        if(t[p].l>=l && t[p].r<=r) return t[p].v;
        pd(p);
        int m=(t[p].l + t[p].r)>>1, res=0;
        if(l<=m) res = qry(p<<1, l, r);
        if(r>m) res = max(res, qry(p<<1|1, l, r));
        return res;
    }
}tr[M];

int main(){
    scanf("%d %d", &n, &k);
    for(int i=1;i<=n;i++){
        scanf("%d", &a[i]);
        pre[i] = pos[a[i]];
        pos[a[i]] = i;
    }
    
    for(int i=1;i<=n;i++){
        dp[i][1] = dp[i-1][1];
        if(!vis[a[i]]){
            vis[a[i]] = 1;
            dp[i][1]++;
        }
    }
    
    for(int j=2;j<=k;j++){
        tr[j-1].clr(j-1, 1, 0, n);
        for(int i=1;i<=n;i++){
            tr[j-1].upd(1, pre[i], i-1, 1);
            dp[i][j] = tr[j-1].qry(1, 0, i-1);
        }
    }
    
    printf("%d", dp[n][k]);
    return 0;
}
相关推荐
闻缺陷则喜何志丹12 小时前
【动态规划 前缀和】P7074 [CSP-J2020] 方格取数|普及+
c++·算法·前缀和·动态规划·洛谷
袁雅倩199721 小时前
当吸尘器、筋膜枪都用上Type-C,供电方案该怎么选?浅谈PD取电芯片ECP5702的应用
c语言·开发语言·支持向量机·动态规划·推荐算法·最小二乘法·图搜索算法
workflower1 天前
从拿订单到看方向
大数据·人工智能·设计模式·机器人·动态规划
workflower1 天前
企业酝酿数智化内驱力
大数据·人工智能·设计模式·机器人·动态规划
是wzoi的一名用户啊~1 天前
Floyd 模版 弗洛伊德算法 模版
c++·算法·动态规划·图论·floyd
故事和你912 天前
蓝桥杯-2026年C++B组省赛
开发语言·数据结构·c++·算法·蓝桥杯·动态规划·图论
我是无敌小恐龙2 天前
Java基础入门Day10 | Object类、包装类、大数/日期类、冒泡排序与Arrays工具类 超详细总结
java·开发语言·数据结构·算法·贪心算法·排序算法·动态规划
cheems95272 天前
[算法手记] 动态规划,二叉树计数问题
算法·动态规划
样例过了就是过了2 天前
LeetCode热题100 编辑距离
数据结构·c++·算法·leetcode·动态规划
khalil10202 天前
代码随想录算法训练营Day-46 动态规划13 | 647. 回文子串、516.最长回文子序列、动态规划总结
数据结构·c++·算法·leetcode·动态规划·回文子串·回文子序列