http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1007
先把数据分成两组,那么必定有一组趋近于所有数的和/2
我们可以把数的和看成包的重量,每个数看成要放入包的物体,这样就能把问题当作01背包处理,找到小于sum/2的最大放入量即可
dp[i][j]代表放入到第i个物体时背包容量为j时数的和,那么dp[i][j]大小由前一个物体放或不放决定
可以得到dp[i][j] = max(dp[i - 1][j], dp[i - 1][j-a[i]] + a[i])
最后得到dp[n][sum/2]表示较小的那一组数之和,那么两组数和之差就是(sum - dp[n][sum/2])-dp[n][sum / 2]
#include<iostream> #include<algorithm> using namespace std; int a[10005], dp[105][10005] = {0},sum=0; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; sum += a[i]; } for (int i = 1; i <= n; i++) for(int j=sum/2;j>=a[i];j--) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j-a[i]] + a[i]); cout << (sum - dp[n][sum/2])-dp[n][sum / 2]; return 0; }