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\n", 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("\n"); } return 0; }