Raucous Rockers
“破锣摇滚”乐队
译 by Maigo Akisame
“破锣摇滚”乐队
译 by Maigo Akisame
你刚刚继承了流行的“破锣摇滚”乐队录制的尚未发表的N(1 <= N <= 20)首歌的版权。你打算从中精选一些歌曲,发行M(1 <= M <= 20)张CD。每一张CD最多可以容纳T(1 <= T <= 20)分钟的音乐,一首歌不能分装在两张CD中。
不巧你是一位古典音乐迷,不懂如何判定这些歌的艺术价值。于是你决定根据以下标准进行选择:
- 歌曲必须按照创作的时间顺序在CD盘上出现。
- 选中的歌曲数目尽可能地多。
PROGRAM NAME: rockers
INPUT FORMAT
第一行: | 三个整数:N, T, M. |
第二行: | N个整数,分别表示每首歌的长度,按创作时间顺序排列。 |
SAMPLE INPUT (file rockers.in)
4 5 2 4 3 4 2
OUTPUT FORMAT
一个整数,表示可以装进M张CD盘的乐曲的最大数目。SAMPLE OUTPUT (file rockers.out)
3
一开始没有想到方程 看到题解后领悟了
因为要求歌曲必须按照创作的时间顺序在CD盘上出现。
所以区间动归可以解决
f[i,j]表示前i张光盘,放前j首歌的最多的数目
决策就是第i张光盘里面放几首歌,枚举即可。
f[i,j]=max(f[i-1,k]+g[k+1,j]) 0<=k<=j-1
g[i,j]表示第i首歌到第j首歌在一个光盘里最多能放歌个个数
由于本题数据规模小,g[i,j]本人直接暴力冒泡搞出。。。
当然本题dfs可过。。o(2^20)
var n,t,m,i,j,k,ji,d1,d2:longint; f:array[0..20,0..20]of longint; g:array[0..20,0..20]of longint; a,b:array[0..20]of longint; function work(l,r:longint):longint; var i,j,s,tot:longint; begin for i:=l to r do b[i]:=a[i]; for i:=l to r-1 do for j:=i+1 to r do if b[i]>b[j] then begin s:=b[i]; b[i]:=b[j]; b[j]:=s; end; s:=0;tot:=0; for i:=l to r do if s+b[i]<=t then begin inc(tot); s:=s+b[i]; end; exit(tot); end; function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end; procedure dp; var i,j,s:longint; begin for i:=1 to m do for j:=1 to n do begin for k:=0 to j-1 do begin f[i,j]:=max(f[i,j],f[i-1,k]+g[k+1,j]); end; end; writeln(f[m,n]); end; begin fillchar(f,sizeof(f),0); fillchar(g,sizeof(g),0); readln(n,t,m); for i:=1 to n do read(a[i]); for i:=1 to n do for j:=1 to n do g[i,j]:=work(i,j); dp; readln;readln; end.