揹包 dp 双重动态规划

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是按照时间顺序的,而且每张碟的歌要比前一张碟出的晚,这就决定了可以把歌曲分成几部分,分别装入到cd中,有m张cd,则问题可描述成,把歌曲分堆,然后各自求最优装载,分别用01揹包算法。由于不知道如何分堆才会产生最优解,所以第一次动态规划算出每个区间段的最优装载,然后第二个动态规划求出最优的分堆。这题可以用双重动态规划求解。

 

 

UASCO的标准解法跟有利于掌握动态规划

分析:

能不能把当前的歌曲放入cd中,取决于一下三个条件:

1.目前cd中耗费的内存

2.当前歌曲长度

3. 最后一张放在cd中的歌曲(因为题目要求歌曲要按时间顺序放入cd)

dp时的维数和各维数的含义就从这里得出

第一维是当前cd数

第二维是目前cd内存的耗费

第三维是最后放入的歌曲

以下是USACO的分析:

 

This is a pretty straight-forward dynamic programming problem. The factors that determine whether we can put a song on a CD are:

  • The length used up on the CD so far
  • The length of the current song
  • The last song that we put on the CD (because of the date restriction)

Therefore, we create an matrix called "dp", with dp[a][b][c] being the most number of songs that we can put on the first 'a' CDs, with 'b' minutes already used up on the 'a'th CD, and with 'c' being the last song that we put on CD 'a'. We initialize the matrix to be all zeroes, and then we cycle through it as follows:

  • We traverse the CDs in ascending order to satisfy the date requirement
  • We go through the number of minutes used in ascending order, so that we have had a chance to put on a song earlier in the CD before we try to put songs on at a later time
  • We go through the last song used in ascending order (although this order doesn't really matter)
  • We go through the new songs in ascending order, making sure to start with songs that were dated after the last song

If the new song that we want to include in the set will fit on the current CD, there is no reason to put it on the next CD, so we check the matrix and see if adding it to the current set of songs will be better than the value already stored in the matrix. Otherwise, we check to see if it would be beneficial to put the song on the next CD. As a time-saver, each time we check a current value in the matrix to see what other songs we can put on the CD, we also check and see if this value is better than the most number of CDs that we have currently been able to fit in the set, so that we don't need to do this at the end. Finally, we output this best number, which will be the most number of CDs that we can fit in the set.

 

发布了20 篇原创文章 · 获赞 8 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章