题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1007

题意:中文题诶~

思路:尽量将一个数组分成两个相等的部分,就是从原数组中选出一些元素使其和尽量接近所有元素的和的一半啦.至于如何选元素,我们可以用01背包解决;

假设原数组所有元素和为sum,那么可以分为 ans1 >= sum/2 和 ans2 <= sum/2 两部分,为了方便我们求 ans2 <=sum/2那部分, 那么此题的答案即为  sum-2*ans2,

接下来我们只要考虑如何用01背包求ans2就好啦;

我们用 dp[i][j] 表示到地 i 个元素为止,选择的元素和小于等于 j 的最大值,那么有 ans2=dp[n][num/2];

状态转移方程式为:

dp[i][j] = max (dp[i-1][j], dp[i-1][j-a[i]]+a[i]) 前者为不选当前元素,后者为选当前元素.注意后者状态的转变,最接近 j-a[i] 的那个数加上 a[i] 自然就是最接近 j 的数啦.

代码:

#include <bits/stdc++.h>
#define MAXN 110
using namespace std; int a[MAXN], dp[MAXN][MAXN*MAXN]; //dp[i][j]存储的到地i个元素为止,可以得到的小于等于j的最大值 int main(void){
int n, sum=;
cin >> n;
for(int i=; i<=n; i++){
cin >> a[i];
sum+=a[i];
}
for(int i=; i<=n; i++){
for(int j=sum/; j>=a[i]; j--){
dp[i][j]=max(dp[i-][j], dp[i-][j-a[i]]+a[i]);//选或不选a[i]
}
}
cout << sum-*dp[n][sum/] << endl;
return ;
}

上述算法的时间复杂度和空间复杂度分别为:O(sum*n), O(sum*n);

我们可以进一步优化一下空间复杂度,通过上面的代码我们不难发现 dp[i][j] 都是由 dp[i-1][j] 得到的,也就是我们是直接由前一步的答案得到后一步结果的,直至得到最终答案.那么我们可以不存储前面的数据.用 dp[j]存储当前能得到的小于等于 j 的最大值,然后逐步更新dp[j]的值就可以得到答案啦;

其空间复杂度为 O(sum)

代码:

 #include <bits/stdc++.h>
#define MAXN 110
using namespace std; int a[MAXN], dp[MAXN*MAXN]; //dp[j]存储可以得到的小于等于j的最大值 int main(void){
int n, sum=;
cin >> n;
for(int i=; i<n; i++){
cin >> a[i];
sum+=a[i];
}
for(int i=; i<n; i++){ //外循环通过选中a[i]来更新dp[j]的值
for(int j=sum/; j>=a[i]; j--){
dp[j]=max(dp[j], dp[j-a[i]]+a[i]);
}
}
cout << sum-*dp[sum/] << endl;
return ;
}

51nod1007(01背包)的更多相关文章

  1. UVALive 4870 Roller Coaster --01背包

    题意:过山车有n个区域,一个人有两个值F,D,在每个区域有两种选择: 1.睁眼: F += f[i], D += d[i] 2.闭眼: F = F ,     D -= K 问在D小于等于一定限度的时 ...

  2. POJ1112 Team Them Up![二分图染色 补图 01背包]

    Team Them Up! Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7608   Accepted: 2041   S ...

  3. Codeforces 2016 ACM Amman Collegiate Programming Contest A. Coins(动态规划/01背包变形)

    传送门 Description Hasan and Bahosain want to buy a new video game, they want to share the expenses. Ha ...

  4. 51nod1085(01背包)

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1085 题意: 中文题诶~ 思路: 01背包模板题. 用dp[ ...

  5. *HDU3339 最短路+01背包

    In Action Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  6. codeforces 742D Arpa's weak amphitheater and Mehrdad's valuable Hoses ——(01背包变形)

    题意:给你若干个集合,每个集合内的物品要么选任意一个,要么所有都选,求最后在背包能容纳的范围下最大的价值. 分析:对于每个并查集,从上到下滚动维护即可,其实就是一个01背包= =. 代码如下: #in ...

  7. POJ 3624 Charm Bracelet(01背包)

    Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 34532   Accepted: 15301 ...

  8. (01背包变形) Cow Exhibition (poj 2184)

    http://poj.org/problem?id=2184   Description "Fat and docile, big and dumb, they look so stupid ...

  9. hdu3339 In Action(Dijkstra+01背包)

    /* 题意:有 n 个站点(编号1...n),每一个站点都有一个能量值,为了不让这些能量值连接起来,要用 坦克占领这个站点!已知站点的 之间的距离,每个坦克从0点出发到某一个站点,1 unit dis ...

随机推荐

  1. .net Core 相关问题

    1.Vs中注释生成xml文档文件 项目->属性->生成->输出->勾选“XML文档文件”->保存  就完成. 保存后出现没有勾选情况,直接用txt打开.csproj文件加 ...

  2. 用一句SQL取出第 m 条到第 n 条记录的方法

    1 --从Table 表中取出第 m 条到第 n 条的记录:(Not In 版本)2 3 SELECT TOP n-m+1 * 4 FROM Table 5 WHERE (id NOT IN (SEL ...

  3. (转)python调取C/C++的dll生成方法

    本文针对Windows平台下,python调取C/C++的dll文件. 1.如果使用C语言,代码如下,文件名为test.c. __declspec(dllexport) int sum(int a,i ...

  4. 【leetcode刷题笔记】Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  5. 【遍历二叉树】06二叉树曲折(Z字形)层次遍历II【Binary Tree Zigzag Level Order Traversal】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的Z字形层次 ...

  6. dbcc练习1

    dbcc tranceon(2588,3604) dbcc ind() dbcc page()

  7. JS undefined

    undefined表示"缺少值",就是此处应该有一个值,但是还没有定义.典型用法是: (1)变量被声明了,但没有赋值时,就等于undefined. (2) 调用函数时,应该提供的参 ...

  8. ssh配置免登 Ubuntu环境

    配置之前,可能需要修改下每台机器的hostname,修改方法 1.直接修改hostname文件:sudo vi /etc/hostname 2.重启服务器:shutdown -r now Ubuntu ...

  9. 基于ftp服务实现yum网络共享

    安装ftp服务:yum install vsftpd 安装后: CentOS7 启动服务:systemctl start vsftpd 设置开机启动:systemctl enable vsftpd 同 ...

  10. 通过 命令提示符(cmd.exe)连接 Oracle 数据库

    通过IP 连接数据库: sqlplus userName/userPassword@//IP:port/SID 例:sqlplus testuser/123456@//192.168.0.1:1521 ...