USACO / Raucous Rockers (DP背包模型)

描述

你刚刚继承了流行的“破锣摇滚”乐队录制的尚未发表的N(1 <= N <= 20)首歌的版权。你打算从中精选一些歌曲,发行M(1 <= M <= 20)张CD。每一张CD最多可以容纳T(1 <= T <= 20)分钟的音乐,一首歌不能分装在两张CD中。

不巧你是一位古典音乐迷,不懂如何判定这些歌的艺术价值。于是你决定根据以下标准进行选择:

 1.歌曲必须按照创作的时间顺序在CD盘上出现。
 2.选中的歌曲数目尽可能地多。
 3.不仅同光盘上的歌曲写入时间要按顺序,前一张光盘上的歌曲不能比后一张歌曲写入时间要晚。

格式

PROGRAM NAME: rockers

INPUT FORMAT:

(file rockers.in)

第一行: 三个整数:N, T, M.

第二行: N个整数,分别表示每首歌的长度,按创作时间顺序排列。

OUTPUT FORMAT:

(file rockers.out)

一个整数,表示可以装进M张CD盘的乐曲的最大数目。

SAMPLE INPUT

4 5 2
4 3 4 2

SAMPLE OUTPUT

3

分析:

 
 01背包模型,f[i][j]=Max{f[i-1][j],f[i-1][j-a[i]]+1},当然还要加上1维表示当前在第几个CD,即f[i][j][k]表示到第i首歌用到第j个CD,最后一个CD还剩k分钟能装的最多的歌曲。
  状态转移方程还是很容易想出来的,只是细节处理需要仔细点。

USER: Zhipeng ZHANG [138_3531]
TASK: rockers
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.000 secs, 3212 KB]
   Test 2: TEST OK [0.000 secs, 3212 KB]
   Test 3: TEST OK [0.011 secs, 3212 KB]
   Test 4: TEST OK [0.000 secs, 3212 KB]
   Test 5: TEST OK [0.000 secs, 3212 KB]
   Test 6: TEST OK [0.000 secs, 3212 KB]
   Test 7: TEST OK [0.000 secs, 3212 KB]
   Test 8: TEST OK [0.011 secs, 3212 KB]
   Test 9: TEST OK [0.011 secs, 3212 KB]
   Test 10: TEST OK [0.011 secs, 3212 KB]
   Test 11: TEST OK [0.011 secs, 3212 KB]
   Test 12: TEST OK [0.011 secs, 3212 KB]

All tests OK.

Your program ('rockers') produced all correct answers! This is your submission #9 for this problem. Congratulations!



/*
ID:138_3531
LANG:C++
TASK: rockers
*/

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;

int Max(int a,int b)
{
    return a>b?a:b;
}

int main()
{
    freopen("rockers.in","r",stdin);
    freopen("rockers.out","w",stdout);

    int n,m,t;
    int a[25];
    int f[25][25][25];
    memset(f,0,sizeof(f));
    cin>>n>>t>>m;
    for (int i=1;i<=n;i++)
        cin>>a[i];
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            for (int k=0;k<=t;k++)          //细节,k=0
            {
                f[i][j][k]=f[i-1][j][k];
                if (t>=a[i])          
                {
                    if (k>=a[i])
                        f[i][j][k]=Max(f[i][j][k],f[i-1][j][k-a[i]]+1);
                    if (j>1)              //这里很重要,还是一步一步调试才发现错的
                    f[i][j][k]=Max(f[i][j][k],f[i-1][j-1][t-a[i]]+1);
                }
            }

    cout<<f[n][m][t]<<endl;
    return 0;
}
 
举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
原文地址:https://www.cnblogs.com/AbandonZHANG/p/2622746.html