01背包;感谢ZCK大佬

题目描述

学校举行拔河比赛,所有的人被分成了两组,每个人必须(且只能够)在其中的一组,要求两个组的人数相差不能超过1,且两个组内的所有人体重加起来尽可能地接近。

输入

输入中的第一行只有一个整数n(1≤n≤100),第二行有n个以空格分隔的整数,表示每人的体重wi(所有的wi均满足:1≤wi≤450)。

输出

输出只有一行,该行有两个整数,以一个空格分隔。第一个数表示体重较大的组的体重总和,第二个数表示体重较小的组的体重总和。

题面看上去很短,题意也很好理解:就是将n个人分成两组,在人数差不大于1的情况下使它们差最小。

用cnt表示它们的体重之和,则是使两组重量之和尽可能接近cnt / 2。那么就是在cnt / 2的空间里尽可能地使选入的人重。乍一看跟“挤牛奶”没区别,都是两维的dp其中增加一位限制人数。i,j,k三维循环,

for (int i=; i<=n; i++)
for (int j=i; j>=; j--)
for (int k=cnt; k>=a[i]; k--)
因为每个人只能选一次,所以j,k逆序

i,j,k循环


先来讲讲我最早的想法:

这是一份80,一份90的代码

初始化是f[][] = 0

在这种dp[][]方程的定义下,f[i][j]表示1..i人,凑成0..j范围内能凑成的最大重量(我知道这非常奇怪。事实上,在请教ZCK之前我甚至以为这个f[i][j]表示i个人能否凑出j。所以我发现"当f[i][j] != 0时,f[i][j] != j "这个现象时候才开始怀疑我的dp方程)

f[j][k] = max(f[j][k], f[j-1][k-a[i]]+a[i]);

在最终选取ans的时候,由于我们希望ans最接近cnt / 2,那么循环是“cnt / 2 ... 1“的,则ans = max{f[n / 2][]}。在这种情况下,不能够只判断 f[n / 2][i] 。虽然这看上去很有道理——如果n是奇数,用cnt - f[n / 2][i]就是奇数那一队的人数嘛!ZCK解释说:“f[n / 2][] 和 f[n / 2+1][] (n为奇数)是两条不同的数轴,不能保证f[n / 2][]上最接近cnt / 2的值比f[n / 2+1][]上的更优。”由于我们枚举的f[n / 2][] ≤ cnt / 2,那么对应的f[n / 2+1][]就是 ≥ cnt / 2的。有可能n / 2+1人能凑出更接近cnt / 2的!

可能会想到:既然dp时候已经把f[][cnt ... 1]都表示出来了,那么只需要在寻找ans的时候改动一下,变成这样

for (int j=cnt; j>=1; j--)
{
if (abs(cnt - 2*f[n/2][j]) < abs(cnt-2*ans))ans = f[n/2][j]
}

实际上,这样的判断只有70分。

并不是因为寻找ans的过程有问题,是因为f[][]所表示的东西不是我们想要的


这原因是初始化。

memset(f,-127,sizeof(f));  将f初始化为一个很小很小的数,这样f[i][j]表示的东西就不一样了
f[0][0]=0;  必要的

这样改了之后,只需要"cnt ... 1"判f[n / 2][]即可.

当然"cnt / 2 ... 1"判f[n / 2][], f[n / 2+1][]也可

因为我的dp方程太凌乱了……为了阿掉这题爆交共30+……


ZCK:你的dp方程到底想表示什么???直接bool不就好了吗

bool f[103][45035];

实际上,这的确是最简洁而且dp方程表示最明确的一种方法……


讲了这么多,实际上只是想说明dp方程的 定义 和 初始化 对于dp来说有多么重要。短短的一句初始语句或者在脑海中闪过一瞬的dp方程碎片,就足以上演化爆零为AC的奇迹。一个max和一个if看上去没多大差别,事实上后续的处理可能失之千里。考虑问题要仔细全面,这绝对不是一句空话。

【dp】拔河比赛的更多相关文章

  1. codevs 1959 拔河比赛--判断背包内刚好装满n/2个物品

    1959 拔河比赛  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 一个学校举行拔河比赛,所有的 ...

  2. codevs1959拔河比赛(二维费用背包)

    1959 拔河比赛  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold     题目描述 Description 一个学校举行拔河比赛,所有的人被分成了两组,每个人 ...

  3. CODEVS 1959 拔河比赛(另一版本)

    题目描述 Description 一个学校举行拔河比赛,所有的人被分成了两组,每个人必须(且只能够)在其中的一组,要求两个组的人数相差不能超过1,且两个组内的所有人体重加起来尽可能地接近. 输入描述 ...

  4. rqnoj71 拔河比赛

    题目描述 superwyh的学校要举行拔河比赛,为了在赛前锻炼大家,老师决定把班里所有人分为两拨,进行拔河因为为锻炼所以为了避免其中一方的实力过强老师决定以体重来划分队伍,尽 量保持两个队伍的体重差最 ...

  5. c 指针 及其位运算循环移动拔河比赛问题代码

    week_2_day1_7.7 周一//用字符数组 来实现 字母大小写转换#include<stdio.h>void desc( char *a ,int n){    char  *i ...

  6. [深搜]A. 【例题1】拔河比赛

    A . [ 例 题 1 ] 拔 河 比 赛 A. [例题1]拔河比赛 A.[例题1]拔河比赛 解析 模板题,选与不选 Code #include <bits/stdc++.h> #defi ...

  7. 【C/C++】拔河比赛/分组/招商银行

    题目:小Z组织训练营同学进行一次拔河比赛,要从n(2≤n≤60,000)个同学中选出两组同学参加(两组人数可能不同).对每组同学而言,如果人数超过1人,那么要求该组内的任意两个同学的体重之差的绝对值不 ...

  8. 【codevs1959】拔河比赛

    题目大意:给定一个有 N 个数的集合,将这 N 个数均分成两堆,求差值最小是多少. 题解:有关集合选数的问题,应该是背包问题,同时要求均分可知,选出的物品数目也应该是背包费用的一个维度,因此这是一个多 ...

  9. 【解题报告】[动态规划]RQNOJ - PID72 / 拔河比赛

    原题地址:http://www.rqnoj.cn/problem/72 解题思路:基本的01背包问题. 要求的就是在这些人中选出一些人,使得这些人的体重的和 不超过所有人的体重的一半 并最大. 代码: ...

随机推荐

  1. 阿里巴巴开源性能监控神器Arthas初体验

    如果问性能测试中最难的是哪部分,相信很多人会说“性能调优”.确实是这样,性能调优是一个非常复杂.技术含量很高的工作.涉及到的知识面很广.以我多年从业经验来看,在企业里,大多数的性能调优都是由开发架构师 ...

  2. java基础第二篇

    3.选择结构 a.if: 格式一: if(表达式1){ 表达式1为真才执行 } 格式二: if(表达式1){ 表达式1为真才执行 }else{ 表达式1位假才执行 } 格式三:判断工龄的范围,判断成绩 ...

  3. seq(2018.10.24)

    一道\(dp\)题... 期望\(40\)分解法 预处理:离散化,然后让连续一段值相同的元素合并为一个元素. 正式\(DP\): 显然有个最差策略为每个元素处都切一次,则切的次数为元素的个数\(-1\ ...

  4. hdu 6299 Balanced Sequence( 2018 Multi-University Training Contest 1 )

    #include <stdio.h> #include <iostream> #include <cstdlib> #include <cmath> # ...

  5. 自动化脚本- 安装更换Python3.5

    本脚本所有信息: 1:判断是不是root用户,是则继续不是则退出脚本输出信息2:定义自己的版本3:根据用户输入的版本号,来下载对应的版本包4:使用系统命令wget来下载,注意wet后面有一个空格5:o ...

  6. SpringBoot | 启动异常 | 显示bulid success 无 error信息

    可能原因是没有添加 web 依赖,检查pom里面是否有web <dependency> <groupId>org.springframework.boot</groupI ...

  7. JAVASCRIPT一维数转化为二维数组

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  8. zabbix图表中文乱码

    如果语言改成中文,在图表中的中文会乱码,这是因为zabbix默认的字体文件比较烂 方法就是把字体文件替换,找到zabbix前端文件地址,换一个字体文件就好 [root@webmaster fonts] ...

  9. Mysql的跨服务器操作

    1.查询FEDERATED功能是否开启: show ENGINES; 2.如果状态为NO则需修改my.ini文件,增加一行federated配置: my.ini配置文件的默认路径 C:\Program ...

  10. scrapy分布式原理

    scrapy分布式原理   关于Scrapy工作流程回顾 Scrapy单机架构 上图的架构其实就是一种单机架构,只在本机维护一个爬取队列,Scheduler进行调度,而要实现多态服务器共同爬取数据关键 ...