01背包的变形,看成价值和重量相等的01背包,设总和为sum,则背包总容量为sum/2,往这个背包里填,使之最接近sum/2,则剩下的与装进去

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100;
const int M = 10000;
int sum,n,m;
int v[N+10],w[N+10];
int dp[N+10][M+10];
void DP()
{
    for(int i=1; i<=n; i++){
        for(int j = 0; j<=sum/2;j++){
            if(w[i]<=j)
                dp[i][j] = max(dp[i-1][j-w[i]]+v[i],dp[i-1][j]);
            else 
                dp[i][j] = dp[i-1][j];
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    cin>>n;
    for(int i = 1; i<=n; i++){
        cin>>w[i]; sum+=w[i]; v[i]=w[i];
    }
    DP(); 
    cout<<abs(sum-dp[n][sum/2]*2)<<endl;
    return 0;
}

的差就会最小。