题目链接

http://acm.timus.ru/problem.aspx?space=1&num=1005

题目大意

给你一堆石头,现在需要你将这堆石头分成两堆,要求两堆石头的重量相差最小,求这个最小的值是多少。

解题思路

看完题目之后,我们可以了解一下数据的规模,最多就20个石头,所以我们可以列出我们能够解题的一些方法:

  • 直接深度优先搜索,暴力得到每一种划分方法
  • 二进制枚举,这也是一种暴力求解方法
  • 将题目转化为01背包问题,动态规划求解

结合题目时间限制,我们最终选择第三种方法。所以现在来重点讲解下,这个题目需要怎么转化为01背包问题的。

首先,将石头划分成AB两堆,那么我们相当于从一堆石头里面挑选出若干个石头出来。对于每一块石头都有挑选或者不挑选两种选择。这就有点像01背包问题了,但是目前还不确定如何用01背包来求解。题目要求我们求解两堆石头的最小差,如果石头是可以掰开的,那么最理想的状态当然是两堆石头的重量都是原始那堆石头重量的一半avg,但是现实不是那么完美的,我们不能将石头掰开揉碎,而且很有可能最终的最好结果确实是一堆重一堆轻。

假设最优的结果是一堆石头重量为A,另外一堆是B,那么AB两者可能是其中一个大于等于avg,另外一个是小于等于avg。我们现在需要使|A-B|最小,那么最好是AB越靠近avg越好,这就相当于我们拿一个最大承重为avg的袋子去装石头,最多能装多少重量的石头。这就是一个01背包问题了。接下来我们只要求出这个背包问题的解,那么最后的差也就能够计算出来了。

解题代码

#include <cstdio>
#include <algorithm>
using namespace std; int n;
int wights[25];
int dp[25][100000*10+10]; int pack01(int volume) {
for (int i = 0; i <= volume; ++i) {
dp[0][i] = 0;
}
for (int i = 1; i <= n; ++i) {
for (int v = 0; v <= volume; ++v) {
if (v >= wights[i-1]) {
dp[i][v] = max(dp[i-1][v], dp[i-1][v-wights[i-1]]+wights[i-1]);
} else {
dp[i][v] = dp[i-1][v];
}
}
}
return dp[n][volume];
} int main() {
while (~scanf("%d", &n)) {
int tot = 0;
for (int i = 0; i < n; ++i) {
scanf("%d", &wights[i]);
tot += wights[i];
}
int ans = pack01(tot/2);
printf("%d\n", tot-2*ans);
}
return 0;
}

但是这种写法是有问题的,会超内存。所以我们应该用滚动数组来进行空间优化。

#include <cstdio>
#include <algorithm>
using namespace std; int n;
int wights[25];
int dp[100000*10+10]; int pack01(int volume) {
for (int i = 0; i <= volume; ++i) {
dp[i] = 0;
}
for (int i = 1; i <= n; ++i) {
for (int v = volume; v >= 0; --v) {
if (v >= wights[i-1]) {
dp[v] = max(dp[v], dp[v-wights[i-1]]+wights[i-1]);
}
}
}
return dp[volume];
} int main() {
while (~scanf("%d", &n)) {
int tot = 0;
for (int i = 0; i < n; ++i) {
scanf("%d", &wights[i]);
tot += wights[i];
}
int ans = pack01(tot/2);
printf("%d\n", tot-2*ans);
}
return 0;
}

我之所以解这个题目是因为,网易今年笔试出了一个这样的题目:

一种双核CPU的两个核能够同时处理任务,现在有n个一直数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb数据,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案处理完这批任务所需要的时间最少,求这个最小的时间。

数据规模:

任务数最多为50个,每个任务的大小都是1024kb的整数倍,最大为4194304kb.

对于这样一种规模的数据,我们就绝对不能再暴力求解了。动态规划是一个很好的选择,但是在实际操作的过程中,我们需要注意空间的问题,因为每个任务都是1024kb的整数倍,所以我们可以将数据放缩到1到4096,这样再去解题才能通过。

Timus 1005 解题报告的更多相关文章

  1. POJ 1005 解题报告

    1.题目描述   2.解题思路 好吧,这是个水题,我的目的暂时是把poj第一页刷之,所以水题也写写吧,这个题简单数学常识而已,给定坐标(x,y),易知当圆心为(0,0)时,半圆面积为0.5*PI*(x ...

  2. hdu 1005解题报告

    这道题目n的取值范围很大,1 <= n <= 100,000,000.因此肯定是需要优化才能AC. 首先我考虑到时是有没有通项公式,研究了一下,没发现什么东西,突然看到两个1时就想到会不会 ...

  3. 【NOIP2015】提高day2解题报告

    题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...

  4. ZOJ_3950_How Many Nines 解题报告及如何对程序进行测试修改

    The 17th Zhejiang University Programming Contest Sponsored by TuSimple Solution: #include <stdio. ...

  5. POJ 2054 Color a Tree解题报告

    题干 Bob is very interested in the data structure of a tree. A tree is a directed graph in which a spe ...

  6. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  7. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  8. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  9. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

随机推荐

  1. 企业服务总线ESB

    # 企业服务总线ESB 由中间件技术实现并支持SOA的一组基础架构,支持异构环境中的服务.消息以及基于事件的交互,并且具有适当的服务级别和可管理性. 通过使用ESB,可以在几乎不更改代码的情况下,以一 ...

  2. WebSocket抓包分析

    转载自:https://www.cnblogs.com/songwenjie/p/8575579.html Chrome控制台 (1)F12进入控制台,点击Network,选中ws栏,注意选中Filt ...

  3. 从零开始的Python学习Episode 17——序列化

    序列化 我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语 言中也被称之为serialization,marshalling,flattenin ...

  4. Codeforces Round #524 (Div. 2) C. Masha and two friends(矩形相交)

    C. Masha and two friends time limit per test 1 second memory limit per test 256 megabytes input stan ...

  5. 15 Puzzle (4乘4谜题) IDA*(DFS策略与曼哈顿距离启发) 的C语言实现

    大家好!这是我的第一篇博客,由于之前没有撰写博客的经验,并且也是初入计算机和人工智能领域,可能有些表述或者理解不当,还请大家多多指教. 一.撰写目的 由于这个学期在上算法与数据结构课程的时候,其中一个 ...

  6. Ruby知识点三:运算符

    1.逻辑运算符 (1)条件1 || 条件2 条件1为假时,才需判断条件2 (2)条件1 && 条件2 条件1为真时,才需判断条件2 2.范围运算符 (1)x..y  从x到y,包括y ...

  7. The Art of Multiprocessor Programming读书笔记 (更新至第3章)

    这份笔记是我2013年下半年以来读“The Art of Multiprocessor Programming”这本书的读书笔记.目前有关共享内存并发同步相关的书籍并不多,但是学术文献却不少,跨越的时 ...

  8. 冲刺One之站立会议7 /2015-5-20

    2015-5-20 在登陆成功之后要实现的是聊天界面的交互过程,不同的IP进行信息和数据的传递,这方面我们上学期Java实验里面有过相关的内容,我们把它拿过来改了一下格式,试着看能不能成功,目前还没实 ...

  9. mybatis 原理

    什么是Mybatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为 ...

  10. Python中,os.listdir遍历纯数字文件乱序如何解决

    Python中,os.listdir遍历纯数字文件乱序如何解决 日常跑深度学习视觉相关代码时,常常需要对数据集进行处理.许多图像文件名是利用纯数字递增的方式命名.通常所用的排序函数sort(),是按照 ...