1007 正整数分组

0_1背包问题的变形,这是第一次的错解:DP时把每个物品体积设置为1,导致漏了一些结果。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<cmath>
#include<vector>
#include<string>
using namespace std;
typedef long long LL;
#define M 1000000007
int a[105];
int dp[105][105];
int main()
{
    int t,sum=0;
    scanf("%d",&t);
    for(int i=0;i<t;i++)
    {
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    int m=M,aim,cnt=1,temp=sum;
    while(temp%10==0)
    {
        cnt*=10;
        temp/=10;
    }
    aim = temp/2*cnt;
    sort(a,a+t);
    for(int i=0;i<t;i++)
    {
        if(i==0)
            dp[0][1] = a[i];
        else
        {
            dp[i][0] = dp[i-1][0];
            for(int j=1;j<=t;j++)
            {
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-1]+a[i]);
                if(dp[i][j]-aim>=0)
                    m = min(m,dp[i][j]-aim);
            }
        }
    }
    // 150 75 15 sum-aim-m
    int M1 = max(sum-aim-m,aim+m),M2 = min(sum-aim-m,aim+m);
    printf("%d",M1-M2);
    return 0;
}
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;

const int N=105;

int n,a[N],Sum,Su,dp[N*100];

int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),Sum+=a[i];
Su=Sum/2;
for(int i=1;i<=n;i++){
    for(int j=Su;j>=a[i];j--)dp[j]=max(dp[j],dp[j-a[i]]+a[i]);
}
printf("%d\n",Sum-2*dp[Su]);
return 0;
}
时间: 2024-08-10 02:11:57

1007 正整数分组的相关文章

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行:一个数N,N为正整数的数量. 第2 - N+1行,N个正整数. (N <= 100, 所有正整数的和 <= 10000) Output 输出这个最小差 Input示例 5 1 2 3 4 5 Output示例 1这题不就是小李打怪兽吗,不知道谁模仿谁,呵呵,刚还是我编的题里的,dp,证明一下(要证明什么自

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

1007 正整数分组 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. Input 第1行:一个数N,N为正整数的数量. 第2 - N+1行,N个正整数. (N <= 100, 所有正整数的和 <= 10000) Output 输出这个最小差 Input示例 5 1 2 3 4 5 Output示例 1 题目链接

51 nod 1007 正整数分组 (简单01背包)

http://www.51nod.com/onlineJudge/questionCode.html#problemId=1007&noticeId=15020 求出n个数的和sum,然后用sum/2作为背包容量,让n个数去放,求出一个最大价值,那么这就是其中一组的和,另外一组的和就是sum-dp[sum/2]; 注意这里的体积和价值都是a[i]; 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath&

(DP)51NOD 1007正整数分组

将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. 输入 第1行:一个数N,N为正整数的数量. 第2 - N+1行,N个正整数. (N <= 100, 所有正整数的和 <= 10000) 输出 输出这个最小差 输入样例 5 1 2 3 4 5 输出样例 1解: 1 #include <stdio.h> 2 #include<string.h> 3 int dp[10005]

动态规划&amp;数塔取数&amp;矩阵取数&amp;背包问题&amp;最大子段和&amp;正整数分组

动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.在面试笔试中动态规划也是经常作为考题出现,其中较为简单的DP题目我们应该有百分之百的把握顺利解决才可以. 一.动态规划定义动态规划实际上是一类题目的总称,并不是指某个固定的算法.动态规划的意义就是通过采用递推(或者分而治之)的策略,通过解决大问题的子问题从而解决整体的做法.动态规划的核心思想是巧妙地将问题拆分成多个子问题,通过计算子问题而得到整体问题的解.而子

动规讲解基础讲解八——正整数分组

将一堆正整数分为2组,要求2组的和相差最小.例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的. 整数个数n<=100,所有整数的和<=10000 初看题目,第一想到贪心.怎么贪?排序,每次把数放到“最有利”的一边,最有利指的是每次都把数放到使得结果差值尽可能小的那边.这样的方法显然前两个数只能分到不同的组了,这是不对的.比如{1,2,3},这种贪心会把1和2分开,显然得不到最优解. 最优解是{1,2}在一起,3自己在一组. 是不是如果找到一个

正整数分组(动态规划,但我用的是枚举)

个人心得:这题其实是一个运用动态规划的题目,将n个整数放在俩个背包里,平均下来就是sum/2,此时找到放在背包中最大的就可以了, 此时相减必然是最小的差.而我根据动态规划一步一步得到最优解的思想,从第一个开始枚举,到第n个数会有2^n个数据太大了,n可取100, 听说n=32,就能买下整个拉斯维加斯了.所以我用了stack和set就排重,本来以为会超时,但没想到过了. 题目: 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差

正整数分组

1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include <cstdio> 6 #define _xx ios_base::sync_with_stdio(0);cin.tie(0); 7 using namespace std; 8 typedef long long ll; 9 int dp[10005], a

51nod1128 正整数分组V2

[题解] 二分一个最大值,check一下分出来的组数是否小于等于k即可. 1 #include<cstdio> 2 #include<algorithm> 3 #define LL long long 4 #define rg register 5 #define N 200010 6 int n,k,ans,a[N]; 7 LL l,r,mid; 8 inline int read(){ 9 int k=0,f=1; char c=getchar(); 10 while(c<