题目:题目链接
思路:由于t最大值其实只有180 * 50 + 678,可以直接当成01背包来做,需要考虑的量有两个,时间和歌曲数,其中歌曲优先级大于时间,于是我们将歌曲数作为背包收益,用时间作为背包容量进行dp,记录下最多歌曲数目,最后通过最多歌曲数目得出最多歌曲数目下的最长时间,利用滚动数组我们只需要开一维数组即可
AC代码:
import java.util.Arrays; import java.util.Scanner; public class Main { final public static int maxn = 10000; public static void main(String[] args) { Scanner in = new Scanner(System.in); int T, n, len; int[] f = new int[maxn]; int[] t = new int[55]; T = in.nextInt(); for(int kase = 1; kase <= T; ++kase) { Arrays.fill(f, 0); n = in.nextInt(); len = in.nextInt(); for(int i = 0; i < n; ++i) t[i] = in.nextInt(); int _max = 0; for(int i = 0; i < n; ++i) { for(int j = len - 1; j >= t[i]; --j) { if(f[j - t[i]] >= 1 || j == t[i]) { f[j] = Math.max(f[j], f[j - t[i]] + 1); _max = Math.max(_max, f[j]); } } } int i; for(i = len - 1; f[i] != _max; --i) ; if(_max == 0) System.out.format("Case %d: %d %d ", kase, 1, 678); else System.out.format("Case %d: %d %d ", kase, _max + 1, i + 678); } in.close(); } }