求助各位大佬看下我的思路哪里有问题(能举个反例就更好了,想了半天没想出来)
我想的是二维01背包+装箱问题
假设给了 n 个数,分别为ai,和为 sum
令 m=2n+1,tar=2sum
则问题可以转换为: 物品拥有二维体积,第一维体积都为1,第二维体积为 ai,价值为 ai。
背包一维容量为 m,二维容量为 tar,问这个背包能装到的最大价值为多少
主体代码为
public static void main(String[] args) throws IOException {
n = nextInt();
m = (n+1)/2;
a = new int[n + 1];
int sum=0;
for(int i=1;i<=n;i++){
a[i]=nextInt();
sum += a[i];
}
int tar = (sum+1)/2;
f = new int[m+1][tar+1];
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--)
for(int k=tar;k>=a[i];k--){
f[j][k]=Math.max(f[j][k],f[j-1][k-a[i]]+a[i]);
}
int ans1=f[m][tar],ans2 = sum-ans1;
cout.println(Math.min(ans1,ans2)+" "+Math.max(ans1,ans2));
cout.flush();
} // End of main
完整代码
import java.io.*;
public class Main {
static int status;
static BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static PrintWriter cout = new PrintWriter(bw);
static StreamTokenizer st = new StreamTokenizer(buf);
public static int nextInt() throws IOException {
status = st.nextToken();
return (int) st.nval;
}
public static long nextLong() throws IOException {
status = st.nextToken();
return (long) st.nval;
}
public static String nextString() throws IOException {
status = st.nextToken();
return st.sval;
}
static int n, m, k;
static int[] a;
static int[][] f;
public static void main(String[] args) throws IOException {
n = nextInt();
m = (n+1)/2;
a = new int[n + 1];
int sum=0;
for(int i=1;i<=n;i++){
a[i]=nextInt();
sum += a[i];
}
int tar = (sum+1)/2;
f = new int[m+1][tar+1];
for(int i=1;i<=n;i++)
for(int j=m;j>=1;j--)
for(int k=tar;k>=a[i];k--){
f[j][k]=Math.max(f[j][k],f[j-1][k-a[i]]+a[i]);
}
int ans1=f[m][tar],ans2 = sum-ans1;
cout.println(Math.min(ans1,ans2)+" "+Math.max(ans1,ans2));
cout.flush();
} // End of main
}