http://acm.hdu.edu.cn/showproblem.php?pid=2639
题目大意是,往背包里赛骨头,求第K优解,在普通01背包的基础上,增加一维空间,那么F[i,v,k]可以理解为前i个物品,放入容量v的背包时,第K优解的值。时间复杂度为O(NVK)。
Talk is cheap.
看代码吧。
import java.util.Scanner; public class BoneCollector { public static void main(String[] sure) { int t; Scanner sc = new Scanner(System.in); t = sc.nextInt(); while (t-- > 0) { int n, v, k; n = sc.nextInt(); v = sc.nextInt(); k = sc.nextInt(); int[] val = new int[n + 1]; int[] vol = new int[n + 1]; int[][] dp = new int[v + 2][k + 2]; int[] tp_a = new int[k + 2]; int[] tp_b = new int[k + 2]; for (int i = 0; i < n; i++) { val[i] = sc.nextInt(); } for (int i = 0; i < n; i++) { vol[i] = sc.nextInt(); } for (int i = 0; i < n; i++) { for (int j = v; j >= vol[i]; j--) { for (int m = 1; m <= k; m++) { tp_a[m] = dp[j][m]; tp_b[m] = dp[j - vol[i]][m] + val[i]; } int tmp = 1, a = 1, b = 1; tp_a[k+1] = tp_b[k+1] = -1; //循环,依次将前K优的存到dp数组 while (tmp <= k && (a <= k || b <= k)) { if (tp_a[a] > tp_b[b]) { dp[j][tmp] = tp_a[a]; a++; } else { dp[j][tmp] = tp_b[b]; b++; } if (dp[j][tmp] != dp[j][tmp - 1]) tmp++; } } } System.out.println(dp[v][k]); } } }
原文:http://www.cnblogs.com/aboutblank/p/4345833.html