[NOIP2004]合唱队形【动态规划】

来源:互联网 发布:java 文件夹监听 编辑:程序博客网 时间:2024/05/16 05:20

【问题描述】

    N
位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。

    
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为12…K,他们的身高分别为T1T2TK  则他们的身高满足T1<...Ti+1>…>TK(1<=i<=K)

    
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

【输入文件】

    
输入文件chorus.in的第一行是一个整数N(2<=N<=100),表示同学的总数。第一行有n个整数,用空格分隔,第i个整数Ti(130<=Ti<=230)是第i位同学的身高(厘米)

【输出文件】

    
输出文件chorus.out包括一行,这一行只包含一个整数,就是最少需要几位同学出列。

解题思路:这题的方法还是比较明显的,就是经典的最长不降与不升子序列的结合,枚举1到n作为中间的人,中间为i时,DP求出1到i的最长不降子序列和i到n的最长不升子序列,注意求出来之后i一定要在序列中,然后不断更新答案即可。

 

代码(前几年的代码都年代久远了QAQ):

program chorus(input,output);var f:array[1..150]of longint;a,ff:array[1..150]of longint;i,n,k:longint;function dps(s,e:longint):longint;var i,j:longint;beginfor i:=s to e do for j:=s to i do  if (a[j]<=ff[j]) thenff[i]:=ff[j]+1;dps:=0;for i:=s to e do if ff[i]>dps then dps:=ff[i];for i:=1 to n do ff[i]:=1;end;function dpj(s,e:longint):longint;var i,j:longint;beginfor i:=s to e do for j:=s to i do  if(a[j]>a[i])and(ff[i]<=ff[j]) then ff[i]:=ff[j]+1;dpj:=0;for i:=s to e do if ff[i]>dpj then dpj:=ff[i];for i:=1 to n do ff[i]:=1;end;beginreadln(n);for i:=1 to n do read(a[i]);fillchar(f,sizeof(f),1);for i:=1 to n do ff[i]:=1;k:=maxlongint;for i:=1 to n do begin f[i]:=n-(dps(1,i)+dpj(i+1,n)); if f[i] end;writeln(k);end.


0 0
原创粉丝点击