1. 程式人生 > >uva 473(dp)

uva 473(dp)

return uva rac stdio.h keyword number tdi ++ ack

題意:按創作時間給出n首歌每首歌的時間ti,然後按創作時間裝到m個光盤內,給出光盤最大分鐘數t,問m個光盤最多總共放多少首歌。
題解:對於每首歌都能夠選或者不選,假設選擇了這首歌,是否把這首歌當做第j張光盤的第一首歌。

f[i][j][k]表示前i首歌放到第j張光盤裏用分鐘數是k的容量最多放多少首歌。
f[i][j][k] = f[i - 1][j][k]表示要選這首歌
f[i][j][k] = max(f[i][j][k], f[i][j - 1][t] + 1)表示把這首歌當做第j張光盤的第一首歌
f[i][j][k] = max(f[i][j][k], f[i][j][k-a[i]] + 1)表示不選這首歌當第j張光盤第一首歌
假設用二維滾動數組取代第一維,j要逆序枚舉。

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 1000;
int n, m, t, f[N][N], a[N];

int main() {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        memset(f, 0, sizeof(f));
        scanf("%d%d%d", &n, &t, &m);
        for
(int i = 1; i <= n; i++) scanf("%d%*c", &a[i]); for (int i = 1; i <= n; i++) { for (int j = m; j >= 1; j--) { for (int k = t; k >= a[i]; k--) { f[j][k] = max(f[j][k], f[j - 1][t] + 1); f[j][k] = max(f[j][k], f[j][k - a[i]] + 1
); } } } printf("%d\n", f[m][t]); if (cas) printf("\n"); } return 0; }

uva 473(dp)