将元素平分成差值最小的两个集合(DP)

Posted JmFv5

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将元素平分成差值最小的两个集合(DP)相关的知识,希望对你有一定的参考价值。

 

现有若干物品,要分成较为平均的两部分,分的规则是这样的:

1)两部分物品的个数最多只能差一个。

2)每部分物品的权值总和必须要尽可能接近。

现在请你编写一个程序,给定现在有的物品的个数以及每个物品的权值,求出按上述规则分成两部分后每部分的权值总和。

 

输入格式

第一行为一个整数n(1≤n≤200),表示现在有的物品的个数。

以下的n行每行一个整数,表示每个物品的权值(1≤ai≤40)。

输出格式

只有一行,包含两个数,即分成的每部分的权值总和,较小的一个值放在前面,两个数用空格隔开。

样例输入

3
35
20
32

样例输出

35 52

 

 

对于本题,因为需要再计算过程中保证你计算的结果是n\2 或 n\2+1个物品。所以这个时候我们就必须要使用二维数组,来记录你使用物品个数。

最后我们在找出n\2 或 n\2+1(n是奇数)个物品中权值最大的就行了。

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <sstream>
13 #include <ctime>
14 const int INF=0x3f3f3f3f;
15 typedef long long LL;
16 const int mod=1e9+9;
17 const LL MOD=1e9+7;
18 const double PI = acos(-1);
19 const double eps =1e-8;
20 #define Bug cout<<"---------------------"<<endl
21 const int maxn=1e5+10;
22 using namespace std;
23 
24 int a[205];
25 int dp[205][205*20];//dp[i][j]表示当前有i个物品总权值为j 
26 
27 int main()
28 {
29     #ifdef DEBUG
30     freopen("sample.txt","r",stdin);
31     #endif
32 //    ios_base::sync_with_stdio(false);
33 //    cin.tie(NULL);
34     
35     int n;
36     scanf("%d",&n);
37     int sum=0;
38     for(int i=1;i<=n;i++)
39     {
40         scanf("%d",&a[i]);
41         sum+=a[i];
42     }
43     dp[0][0]=1;
44     for(int i=1;i<=n;i++)
45     {
46         for(int j=n/2+1;j>=0;j--)
47         {
48             for(int k=sum/2;k>=0;k--)
49             {
50                 if(dp[j][k]) dp[j+1][k+a[i]]=1;
51             }
52         }
53     }
54     for(int i=sum/2;i>=0;i--)
55     {
56         if(dp[n/2][i]||(dp[n/2+1][i]&&n&1))
57         {
58             printf("%d %d\n",i,sum-i);
59             break;
60         }
61     }
62     
63     return 0;
64 }

 

 

 

 

 

 

-

以上是关于将元素平分成差值最小的两个集合(DP)的主要内容,如果未能解决你的问题,请参考以下文章

如何将一个集合分成两个子集,以使两个集合中数字之和之间的差异最小?

leetcode困难2163删除元素后和的最小差值

二分数组差值最大

bzoj2064: 分裂(集合DP)

bzoj2064分裂(dp)

python编程,把一个整数list分成两个list,要求两个(list里整数总和)之差值最小