[动态规划]3.4.4 Raucous Rockers

Raucous Rockers
“破锣摇滚”乐队

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值