面试题:数组划分成两个子数组,和的差值的绝对值最小

01背包问题,好久没写,我的代码不是很好看,而且没测试

#include <iostream>
#include <string>
#include <memory.h>
#include <vector>
using namespace std;

//给定一个数组,分成两组后,求两组的和的差的绝对值最小。
//元素值大于0,没有负数;元素个数小于100
/*
思路:背包问题,求最接近sum/2的子数组即可。
*/
int dp[101][10001];
int fun(vector<int> &arr)
{
    int sum = 0;
    int n = arr.size();
    int i;
    for(i = 0 ; i < n ; ++i)
    {
        sum += arr[i];
    }
    int sumorg = sum;
    sum = sum/2;
    for(i = 0 ; i <= sum ; ++i)
    {
        dp[0][i] = 0;
    }
    int j;
    for(i = 1 ; i <= n ; ++i)
    {
        for(j = arr[i-1]; j <= sum ; ++j)
        {
            dp[i][j] = max(dp[i][j],dp[i-1][j-arr[i-1]+arr[i-1]);
        }
    }
    return abs(sumorg,dp[n][sum]);
}

int main()
{
    return 0;
}

这是网上别人的代码:

#include <iostream>
#include <cstdio>
#include <cstring>                  //for memset 
#include <algorithm>                //for max
using namespace std;
const int M = 100 + 10;
int w[M];
int dp[M*100];
bool state[M][M];
int main()
{
    int n;
    while (scanf("%d", &n) != EOF) {
        int sum = 0;
        for (int i = 0; i < n; ++i) {
            scanf("%d", &w[i]);
            sum += w[i];
        }
        memset(dp, 0, sizeof(dp));
        memset(state, 0, sizeof(state));
        for (int i = 0; i < n; ++i)
            for (int j = sum/2; j >= w[i]; --j) {
                if (dp[j] < dp[j-w[i]] + w[i]) {
                    dp[j] = dp[j-w[i]] + w[i];
                    state[i][j] = true;
                }
            }
        printf("%d
", sum - dp[sum/2]*2);
        int i = n, j = sum/2;
        while (i--) {
            if (state[i][j]) {
                printf("%d ", w[i]);
                j -= w[i];
            }
        }
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/cane/p/3863430.html