算法:DP
时间复杂度:$O(N \times M \times T)$
状态表示:
$f[i][j][k]$:从 $1 - i$ 首歌曲中选,恰好在第 $j$ 张唱片且总时长不超过 $k$ 的所选歌曲数量的最大值。
状态计算:
不选第 $i$ 首歌曲:$f[i][j][k] = f[i - 1][j][k]$。
选择第 $i$ 首歌曲:
- 第 $i$ 首歌曲放入之前唱片:$f[i][j][k] = f[i - 1][j][k - v_i] + 1$。
- 第 $i$ 首歌曲新开一个唱片:$f[i][j][k] = f[i - 1][j - 1][t] + 1$。
C++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 25;
int n, t, m;
int f[N][N][N];
int main()
{
cin >> n >> t >> m;
for (int i = 1; i <= n; ++i) {
int v;
cin >> v;
for (int j = 1; j <= m; ++j) {
for (int k = 0; k <= t; ++k) {
f[i][j][k] = f[i - 1][j][k];
if (k >= v) {
f[i][j][k] = max(f[i][j][k], f[i - 1][j][k - v] + 1);
f[i][j][k] = max(f[i][j][k], f[i - 1][j - 1][t] + 1);
}
}
}
}
cout << f[n][m][t] << endl;
return 0;
}
怎么感觉
f[i][j][k]:从 1−i 首歌曲中选,恰好在第 j 张唱片且总时长不超过 k 的所选歌曲数量的最大值。
应该是f[i][j][k]:从 1−i 首歌曲中选,恰好在*前* j 张唱片且总时长不超过 k 的所选歌曲数量的最大值。
👍