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

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

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

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

输入格式

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

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

输出格式

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

样例输入


样例输出

 

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

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

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <ctime>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const LL MOD=1e9+;
const double PI = acos(-);
const double eps =1e-;
#define Bug cout<<"---------------------"<<endl
const int maxn=1e5+;
using namespace std; int a[];
int dp[][*];//dp[i][j]表示当前有i个物品总权值为j int main()
{
#ifdef DEBUG
freopen("sample.txt","r",stdin);
#endif
// ios_base::sync_with_stdio(false);
// cin.tie(NULL); int n;
scanf("%d",&n);
int sum=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
dp[][]=;
for(int i=;i<=n;i++)
{
for(int j=n/+;j>=;j--)
{
for(int k=sum/;k>=;k--)
{
if(dp[j][k]) dp[j+][k+a[i]]=;
}
}
}
for(int i=sum/;i>=;i--)
{
if(dp[n/][i]||(dp[n/+][i]&&n&))
{
printf("%d %d\n",i,sum-i);
break;
}
} return ;
}

现有N个物品,每块物品有一个权值, 现在想将这N个物品分成权值相同的两部分,可以从这N个物品中任取M(1≤M≤N)个来构建。但是不知道这些物品能否使分成的两部分具有同样的权值,也不

知道如果能分成权值相同的两部分,每部分的最大权值是多少。

给定物品的数量N(1≤N≤100)和每个物品的权值wi ( N个物品的权值总和不超过2000 )。

你的任务是判断能否在这些物品中挑一部分,把他们分成权值相同的两部分,如果能,则输出所能分成两部分的最大权值和,否则输出" Impossible"。

输入格式

输入的第一行为一个数 N,表示物品的数量。

第二行为 N 个数,第 i 个数表示第 i 个物品的权值。

输出格式

输出仅包含一行,如果能分成权值相同的两部分,则输出每部分的最大权值和,否则输出一个字符串"Impossible"。

样例输入

    

样例输出


本题用dp[i][j]表示已处理i件物品,而分成的两部分权值差为j的一种状态。

所以我们对这两部分我们有三种操作

1)把第i个物品放入总权值大的一部分中,大的变得更大

2)把第i个物品放入总权值小的一部分中,然后就会发生两种情况

(1)小的变成大的

(2)小的还是小的

所以我们有三种状态转移方程。对应的代入如上。

 #include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <ctime>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+;
const double PI = acos(-);
const double eps =1e-;
#define Bug cout<<"---------------------"<<endl
const int maxn=1e5+;
using namespace std; int a[];
int dp[][]; int main()
{
#ifdef DEBUG
freopen("sample.txt","r",stdin);
#endif
// ios_base::sync_with_stdio(false);
// cin.tie(NULL); int n;
scanf("%d",&n);
int sum=;
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
memset(dp,-,sizeof(dp));
dp[][]=;
for(int i=;i<=n;i++)
{
sum+=a[i];
for(int j=;j<=sum;j++)
{
if(dp[i-][j] > dp[i][j])//不选(初始化)
dp[i][j] = dp[i-][j];
if(j >= a[i] && dp[i-][j-a[i]] >= )//大 -> 大
dp[i][j] = max(dp[i][j],dp[i-][j-a[i]]);
if(dp[i-][j+a[i]] >= )//小 -> 小
dp[i][j] = max(dp[i][j],dp[i-][j+a[i]]+a[i]);
if(a[i] >= j && dp[i-][a[i]-j] >= )// 小 -> 大
dp[i][j] = max(dp[i][j],dp[i-][a[i]-j]+a[i]-j);
}
}
if(dp[n][]) printf("%d\n",dp[n][]);
else printf("Impossible\n"); return ;
}

-

将元素平分成差值最小的两个集合(DP)的更多相关文章

  1. 【poj3522-苗条树】最大边与最小边差值最小的生成树,并查集

    题意:求最大边与最小边差值最小的生成树.n<=100,m<=n*(n-1)/2,没有重边和自环. 题解: m^2的做法就不说了. 时间复杂度O(n*m)的做法: 按边排序,枚举当前最大的边 ...

  2. 用Scala实现集合中相邻元素间的差值

    欢迎转载,转载请注明出处,徽沪一郎. 概要 代码这东西,不写肯定不行,新学Scala不久,将实际遇到的一些问题记录下来,日后也好查找. 今天讲的是如何计算同一集合中元素两两之间的差值,即求开始集合(a ...

  3. Poj 3522 最长边与最短边差值最小的生成树

    题意:       让你求一颗生成树,使得最长边和最短边长度差值最小. 思路:      额!!!感觉这个思路会超时,但是ac了,暂时没什么别的好思路,那么就先说下这个思路,大牛要是有好的思路希望能在 ...

  4. LD1-K(求差值最小的生成树)

    题目链接 /* *题目大意: *一个简单图,n个点,m条边; *要求一颗生成树,使得其最大边与最小边的差值是所有生成树中最小的,输出最小的那个差值; *算法分析: *枚举最小边,用kruskal求生成 ...

  5. 基于visual Studio2013解决面试题之1101差值最小

     题目

  6. 【方法】list<?> 两个list集合 查找不同元素,求差值

    //方法1 //自己声明list//思路,从list1中删除list2中相同的元素//使用循环遍历对比的方式删除//list1包含list2,list1多与list2//结束得出list1为不相同元素 ...

  7. 传说中的华为Python笔试题——两等长整数序列互换元素,序列和的差值最小(修正)

    有两个序列a,b,大小都为n,序列元素的值任意整形数,无序:要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小. 1. 将两序列合并为一个序列,并排序,得到source ...

  8. find the most comfortable road(并差集,找差值最小的权值)

    find the most comfortable road Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  9. 218。重复元素II(重复元素的下标差值<=K)(哈希)

    给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k. 示例 1: 输入: nums ...

随机推荐

  1. 131-PHP子类可以访问父类public修饰的类成员

    <?php class father{ //定义father类 public function cook(){ return '烹饪'; } } class son extends father ...

  2. webapi------宿主程序

    业务场景: 公司的容器程序需要给前端暴露接口但是代码里面又不想写webapi项目工程就用到了宿主可以达到webapi的效果 1.owin实现 2.其他实现 测试实现如下 1.新建一个控制台程序 2.新 ...

  3. C++ 99表

    #include<iostream> using namespace std; class Sumes { public: int sum; int i, j; }; int main() ...

  4. Spark RDD 算子总结

    Spark算子总结 算子分类 Transformation(转换) 转换算子 含义 map(func) 返回一个新的RDD,该RDD由每一个输入元素经过func函数转换后组成 filter(func) ...

  5. opencv+python+dlib人脸关键点检测、实时检测

    安装的是anaconde3.python3.7.3,3.7环境安装dlib太麻烦, 在anaconde3中新建环境python3.6.8, 在3.6环境下安装dlib-19.6.1-cp36-cp36 ...

  6. django ModelForm在模板中显示中文

    情景再现 修改ModelForm 效果

  7. PGSQL基本操作语句

    ; --更新数据 ,,) ; --插入数据 ORDER BY app_name,flag asc/desc ; --查询数据并且排序 offset ; --查询起点0开始查询,返回5条数据 ORDER ...

  8. java基础源码 (4)--reflect包-AnnotatedElement接口

    接口:AnnotatedElement * Represents an annotated element of the program currently running in this * VM. ...

  9. 前端基础之Html、CSS

    Html.css相关 Html Html结构: 标签 描述 <!DOCTYPE html> 文档声明 <html> 根元素 <head> 头部 <body 主 ...

  10. /etc/apt/sources.list.d

    deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main# deb-src http://ppa.launchpad.net/w ...