开始的时候没有想出算法,上网查题解,居然有人说这题是动态规划……无奈。偶然间看到了上海交大马融牛的解题表格:只有一句话,从前向后扫描。才知道这道题用到的只不过是一个贪心思想。

贪心思想:

把序列划分成尽量多的连续子序列,使得每一个连续子序列都满足如下条件:

1..k每个数字都在这个子序列中出现过一次,并且至少有一个数字只出现过一次。

这样的子序列的个数+1就是答案

贪心思想证明:

要让长度为j的序列全部出现,必须满足第一个数字可以取1..k任意一个,第二个数字可以取1..k任意一个……以此类推

当已经划分成j个子序列并无法向后划分的时候,说明第j+1个数是不能在1..k的范围内自由选择的。所以,最短不出现子序列的长度是k+1.

证毕。

CODE

 1 program POJ1989;//by_poetshy
2 const
3 maxn=100000;
4 var
5 a :array[1..maxn]of longint;
6 v :array[1..maxn]of boolean;
7 i,n,k,j :longint;
8 ans :longint;
9
10 begin
11 readln(n,k);
12 for i:=1 to n do readln(a[i]);
13 j:=0;
14 fillchar(v,sizeof(v),0);
15 for i:=1 to n do
16 begin
17 if not v[a[i]] then
18 begin
19 v[a[i]]:=true;
20 inc(j);
21 end;
22 if j=k then
23 begin
24 fillchar(v,sizeof(v),0);
25 j:=0;inc(ans);
26 end;
27 end;
28 writeln(ans+1);
29 end.