邮票分你一半
时间限制:
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
//用背包做这道题速度较快,用搜索做会超时
//zb的生日那道题用搜索快,用背包较慢
#include<stdio.h> #include<string.h> int main() { int T,n,i,j,sum,f[100001],p[100001]; scanf("%d",&T); while(T--) { memset(f,0,sizeof(f)); memset(p,0,sizeof(p)); sum=0; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&p[i]); sum=sum+p[i]; } for(i=1;i<=n;i++) { for(j=sum/2;j>=p[i];j--) { f[j]=f[j]>f[j-p[i]]+p[i]?f[j]:f[j-p[i]]+p[i]; } } printf("%d\n",sum-2*f[sum/2]); } return 0; }
//用搜索超时 //超时代码 /**#include<stdio.h> #include<math.h> #include<string.h> int sum,total,T,N,price[1000],ans; void dfs(int cur,int sum) { int t; if(N==cur) return; t=(int)fabs(total-sum-sum); if(t<ans) ans=t; dfs(cur+1,sum); dfs(cur+1,sum+price[cur]); } int main() { scanf("%d",&T); while(T--) { int i; total=0; scanf("%d",&N); for(i=0;i<N;i++) { scanf("%d",&price[i]); total+=price[i]; } ans=0x70000000; dfs(0,0); if(N==0) printf("0\n"); else printf("%d\n",ans); } return 0; } //假如两个人分的邮票价值分别是a,b.总价值 sum=a+b; //则价值差就是 temp = abs(a-b) = abs( (sum -b) - b)=abs(sum - 2*b)
-
第一行只有一个整数m(m<=1000),表示测试数据组数。