June 11th 模拟赛C T4 Cleanup Solution

来源:互联网 发布:java刚培训工资 编辑:程序博客网 时间:2024/04/29 06:34

空降题目处
点我点我点我

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.
0 0