June 11th 模拟赛C T4 Cleanup Solution

本文介绍了一个基于动态规划的算法,用于解决如何安排餐厅内不同喜好的顾客分批就餐以减少打扫时间的问题。通过限定每批顾客喜欢菜品的数量,确保了算法效率与最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

空降题目处
点我点我点我

Description:

有N(1<=N<=40000)个奶牛到FJ的餐厅吃饭,餐厅里有M(1<=M<=N)种菜,每头牛有自己喜欢的菜的编号P_i(1<=P_i<=M),每头牛只吃自己喜欢的这道菜。
牛儿们在外面排着队进来,按照排队顺序一批一批进来,每批可以同时进来任意头牛,每一批吃完(注意包括最后一批)都要进行打扫,如果这批牛中一共需要K种菜,那么吃完后的打扫时间为K*K。
请你帮助FJ如何安排各批次使得总打扫时间最少。

Input

第1行:空格隔开的两个整数N和M
第2到N+1行:第i+1行包含一个整数P_i。

Output

输出最少打扫时间。

Solution

又是一个神奇的DP.
使用了神奇的DP式.

已知 Ansn . This is very important!!!
我们一起可以选 x(1xn) 头牛一起进餐,若不同的色数为 j 个,则花费jj.
由此可知, jx 才是优的,否则花费会大于 n .
因此,我们可以这样做:
Pj为当前色数为 j 可选的最左端点,
Lx为颜色为 x 的上一个位置,
Fi为选到第 i 头牛的最小花费.
可得DP式:
Fi=min(Fi,FPj1+j2)
那么问题来了,如何维护 P 呢?
详见下面代码
范围:
2in
1jn+1
初值:
详见下面代码

Program

uses
    math;

var
    x,n,m,i,j,k,ml:longint;
    f,p,l:array [-1..40000] of longint;

begin

    assign(input,'cleanup.in');
    assign(output,'cleanup.out');
    reset(input);
    rewrite(output);

    readln(n,m);
    ml:=trunc(sqrt(n))+1;
    fillchar(l,sizeof(l),255);
    readln(x);
    l[x]:=1;
    f[1]:=1;
    p[1]:=1;
    f[-1]:=maxlongint div 2;
    for i:=2 to n do
    begin
        readln(x);
        p[0]:=i;
        for j:=ml downto 1 do
            if l[x]<p[j] then
                p[j]:=p[j-1];
        f[i]:=i;
        for j:=1 to ml do
            f[i]:=min(f[i],f[p[j]-1]+j*j);
        l[x]:=i;
    end;

    writeln(f[n]);

    close(input);
    close(output);

end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值