题目 :http://www.51nod.com/Challenge/Problem.html#!#problemId=1007

  大意就是给一堆正整数,分成和最接近的两组。

  最开始没什么想法,2^n尝试肯定TLE。查了查发现用的居然是dp.于是又回去看了一下dp算法,大概理解了。

  先贴ac代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath> using namespace std; const int MAX = ; int source[];
int r[][MAX+]; int max(int a,int b)
{
return (a>b?a:b);
} int main()
{
int n=;
int i=;
int j=; int total=;
int half=; cin>>n; for(i=;i<n;i++)
{
scanf("%d",&source[i]);
total+=source[i]; //记得考虑最后total是奇数的情况。
} half=(total% == ?total/:total/+); for(i=;i<;i++)
{
r[i][]=;
} for(i=;i<n;i++)
{
for(j=;j<=half;j++)
{
if(source[i]>j) //r[i][j-1]=r[i-1][j]=r[i-1][j-1]
{
r[i][j]=r[i][j-];
}
else
{
if(i == )
{
r[i][j]=+source[i];
}
else
{
r[i][j]=max(r[i-][j],r[i-][j-source[i]]+source[i]);
}
}
} } cout<<abs(total-*r[n-][half]); return ;
}

  之前在网上查,大部分人都说是01背包,但当时怎么都理解不了……于是换了一种思路:

  dp方法最关键的步骤在于对于要求的问题 Q(n) ,它的答案一定是和之前求过的答案 Q(0) , Q(1) , Q(2) ... Q(n-1) 中的某个答案是有关系的。就这道题目来说,思考的方法是:记Q(n)为给定数中和不超过n的最大组合。就是给定数随便挑,只要和不大于n就行,我们要的是和最大的那组。

  虽然是给定数随便挑,但我们也只能从第一个开始一个一个地看啊。于是,用记m为我们已经看了多少个数。

  于是关键来了。假设我们从前m个数中,找到了一组小于n的最大值(仅仅在前m个数中是最大的,对于前m+1个数就不一定了),也就是说,我们暂时找到了Q(n)。但是因为所有的数还没看完,同时n还没达到目标(所有数的总和除以2)。那么,我们来考虑Q(n+1),有如下几种情况:

  1)Q(n)=Q(n-1),也就是说不需要m+1.那么有两种情况不需要:如果m+1>n,那么肯定Q(n)=Q(n-1)。因为m+1本来就不满足“小于n”。而如果m+1<n,那么也有可能不选,即没有合适的组合。那什么情况下没有合适的组合呢?就是从 1 到 m 随便怎么组合,只要加上m+1,要么大于n,要么小于Q(n-1)。

  2)Q(n)>Q(n-1),根据上面的分析,这里就意味着有这么一个组合,能满足它加上m+1,正好介于Q(n-1)和n之间。那这个组合应该怎么找呢?换个思路,我们要找的Q(n)是小于n的最大和,我们知道这个数是k+(m-1),而我们现在要找到 最大的k 。而恰好我们已经找到了从0到n-1的所有的最大值,因此那个k肯定在这之中,确切来说就是Q(n-(m+1)).

  到此,思路就清晰了。

  

51nod1007-正整数分组(dp)的更多相关文章

  1. 51nod1007:正整数分组 DP

    1007 正整数分组 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 ...

  2. [51NOD1007] 正整数分组(DP,记忆化搜索)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1007 dp(id, s)表示第id个数之前,其中一个集合和为s ...

  3. [51nod] 1007 正整数分组 dp

    将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的.   Input 第1行:一个数N,N为正整数的数量 ...

  4. 51Nod 1007 正整数分组 | DP (01背包)

    Input示例 5 1 2 3 4 5 Output示例 1 分析:2组的差最小,那么每一组都要接近sum/2,这样就转化成了普通的0 - 1背包了 #include <bits/stdc++. ...

  5. 1007 正整数分组 1010 只包含因子2 3 5的数 1014 X^2 Mod P 1024 矩阵中不重复的元素 1031 骨牌覆盖

    1007 正整数分组 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的.   Input 第1行:一个 ...

  6. 51 Nod 1007 正整数分组【类01背包】

    1007 正整数分组 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组, ...

  7. 51Nod 1007:正整数分组(01背包)

    1007 正整数分组  基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 ...

  8. 51nod 1007 正整数分组【01背包变形】

    1007 正整数分组 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 ...

  9. 51Nod 1007 正整数分组 -简单DP

    题意: 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. N<=100 sum<=100 ...

  10. (DP)51NOD 1007正整数分组

    将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的.   输入 第1行:一个数N,N为正整数的数量. 第 ...

随机推荐

  1. TERADATA SQL学习随笔<一>

    此博客内容简介及目录 http://www.cnblogs.com/weibaar/p/6644261.html 最近在TERADATA环境学习SQL.在这里记录一下学习中查过的知识点,作为备案. 目 ...

  2. jira7.3.6的安装步骤

    准备环境:jira7.3需要jdk1.8 1.下载jira需要的版本 https://www.atlassian.com/software/jira/download 2.上传atlassian-ji ...

  3. 基于范围的for循环(C++11)

    C++11新增了一种循环:基于范围的for循环.这简化了一种常见的循环任务:对数组(或容器类,如vector和array)的每个元素执行相同的操作,如下例所示 for语句允许简单的范围迭代:(只遍历, ...

  4. 最小生成树--克鲁斯卡尔算法(Kruskal)

    按照惯例,接下来是本篇目录: $1 什么是最小生成树? $2 什么是克鲁斯卡尔算法? $3 克鲁斯卡尔算法的例题 摘要:本片讲的是最小生成树中的玄学算法--克鲁斯卡尔算法,然后就没有然后了. $1 什 ...

  5. 清北学堂学习总结day2

    今天是钟皓曦大佬讲课,先来膜一波   %%%%% •数论 数论是这次培训的一个重点,那么什么是数论呢? 数论是研究整数性质的东西,所以理论上day2不会涉及小数QwQ (切入正题) •整除性: 设a, ...

  6. python numpy 间的的数据变算公式

    import numpy as np a = np.arange(100) print(np.sum(a))#求和 print(np.mean(a))#平均值 print(np.max(a))#最大值 ...

  7. HDOJ 6508 Problem I. Spell Boost (01背包/DP)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6508 题目: Problem Description Shadowverse is a funny car ...

  8. 解决tcp粘包问题

    目录 什么是粘包(演示粘包现象) 解决粘包 实际应用 什么是粘包 首先只有tcp有粘包现象,udp没有粘包 socket收发消息的原理 发送端可以是一K一K地发送数据,而接收端的应用程序可以两K两K地 ...

  9. java 文件目录树

    1. 目标格式,使用tree命令时,目录树格式如下. public class TreeTest { public static void main(String[] args) { File roo ...

  10. figure 的使用

    1.figure语法及操作(1)figure语法说明 figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, ...