NYOJ 456-邮票分你一半(01背包)
2017-08-12 16:49
225 查看
邮票分你一半
时间限制: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
今天开始刷01背包,总是忘记把dp数组置0,有和我出一样毛病的小伙伴要多多注意。。。。。。
分析:这道题和我上午在HD上刷的一道题很像,本题的背包容量是邮票的分值,因为要分为两份分值相差最小的,所以背包容量就是邮票的总分值sum/2,因为邮票的价值也是自身的分值,所以推出状态转移方程为:dp[j]=max(dp[j],dp[j-s[i]]+s[i])。
#include <iostream> #include<stdio.h> #include<cmath> #include<string.h> using namespace std; int main() { int sum,m,n,s[1010],dp[100010]; scanf("%d",&m); while(m--) { sum=0; memset(dp,0,sizeof(dp)); memset(s,0,sizeof(s)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&s[i]); sum+=s[i]; } for(int i=0;i<n;i++) { for(int j=sum/2;j>=s[i];j--) dp[j]=max(dp[j],dp[j-s[i]]+s[i]); } printf("%d\n",sum-dp[sum/2]-dp[sum/2]); } return 0; }
相关文章推荐
- NYOJ456 邮票分你一半(转化为01背包)
- nyoj 456 邮票分你一半(01背包)
- nyoj 456 邮票分你一半 【母函数】【01背包】
- NYOJ 456 邮票分你一半(01背包)
- NYOJ 456 邮票分你一半(01背包)
- NYOJ 456 邮票分你一半(01背包)
- NYOJ-456 邮票分你一半(典型的01背包问题)
- nyoj456 邮票分你一半(01背包)
- 邮票分你一半(nyoj 456)(平分问题)(01背包)
- NYOJ-456-邮票分你一半(01背包)
- nyoj 01背包 289苹果 325zb的生日 456邮票分你一半
- NYOJ--456--邮票分你一半
- nyoj 456 邮票分你一半(母函数)(背包)
- NYOJ 456 邮票分你一半
- nyoj 456——邮票分你一半——————【背包思想搜索】
- NYOJ-456 邮票分你一半
- NYOJ 456 邮票分你一半
- nyoj 456 邮票分你一半
- HDOJ 题目456 邮票分你一半(01背包)
- NYOJ 456 邮票分你一半