邮票分你一半
时间限制:1000 ms | 内存限制:65535 KB
难度:3
-
描述
- 小珂最近收集了些邮票,他想把其中的一些给他的好朋友小明。每张邮票上都有分值,他们想把这些邮票分成两份,并且使这两份邮票的分值和相差最小(就是小珂得到的邮票分值和与小明的差值最小),现在每张邮票的分值已经知道了,他们已经分好了,你知道最后他们得到的邮票分值和相差多少吗?
-
输入
- 第一行只有一个整数m(m<=1000),表示测试数据组数。
接下来有一个整数n(n<=1000),表示邮票的张数。
然后有n个整数Vi(Vi<=100),表示第i张邮票的分值。
输出 - 输出差值,每组输出占一行。 样例输入
-
2 5 2 6 5 8 9 3 2 1 5
样例输出 -
0 2
思路:转换成背包问题。。我们期望的就是一人一半对吧【如果可以最好,不是的话一定是一个多一个少,那么就求少的能有多少】
#include<stdio.h> #include<string.h> #include<math.h> int max(int x,int y) { if(x>y)return x; else return y; } int main() { int n,i,f[100001],c[1001]; scanf("%d",&n); while(n--) { int t,i; int sum=0; scanf("%d",&t); for(i=1;i<=t;i++) { scanf("%d",&c[i]); sum+=c[i]; } memset(f,0,sizeof(f)); for(i=1;i<=t;i++) { for(int j=sum/2;j>=c[i];j--) { f[j]=max(f[j],f[j-c[i]]+c[i]); } } int len=sum-f[sum/2]-f[sum/2]; if(len<0)len*=-1; printf("%d\n",len); } return 0; }
自己实现的Java代码,比较粗糙。01背包改写的
package org.nyoj456; public class NYOJ456 { public void search(int []array,int num,int sum) { int [][]price=new int[num+1][]; int length=array.length-1; price[0]=new int [sum+1]; for (int i = 1; i<=length; i++) { price[i]=new int [sum+1]; int w=array[i]; for (int j = sum; j>=1; j--) { if (j<w) { price[i][j]=price[i-1][j]; continue; }//如果一个苹果的质量大于空间,,显示不能加入啊 if (price[i-1][j]<price[i-1][j-w]+w)//如何决定要不要这个苹果 { price[i][j]=price[i-1][j-w]+w; } else { price[i][j]=price[i-1][j]; } } } System.out.println(price[num][sum]); } public static void main(String args[]) { int []array={0,2,1,5}; NYOJ456 n=new NYOJ456(); int sum=15; n.search(array,3,4); } }
- 第一行只有一个整数m(m<=1000),表示测试数据组数。