一个整数数组,长度为n,将其分为m份,使得各分的和相等

来源:互联网 发布:腾讯手游模拟器mac版 编辑:程序博客网 时间:2024/04/28 03:27
//题意:
//一个整数数组,长度为n,将其分为m份,使得各分的和相等
//比如:{3,4,2,3,6}可以分成{3,2,4,3,6} m=1;或者 {3,6},{2,4,3} m=2;
//{3,3},{2,4}{6} m=3,所以m最大值为3
//思路:使用多重背包
//首先遍历一次数组arr[n],把数组中最大值maxN和总和sum记录下来
//那么可能的等分为m = sum / maxN
//在这m份中,假设为p份,每份都为sum/m

//然后利用多重背包求每份sum/m;

#include <iostream>#include <vector>#include <map>#include <algorithm>using namespace std;#define MSIZ 1000#define NSIZ 10000int dp[NSIZ];int v, n;int path[NSIZ][MSIZ];int num[NSIZ];typedef struct Node_{int data;int index;}Node;Node arr[MSIZ];vector<vector<int>> vec(MSIZ);int cmp(int a, int b){return a > b;}void zeroPacket(int cost, int value, int index,  int id){int i = 0;for (i = v; i >= cost; i--){if (dp[i] < dp[i - cost] + value){dp[i] = max(dp[i], dp[i - cost] + value);memcpy(path[i], path[i - cost], sizeof(path[i - cost]));path[i][index] = id;}}}void completePacket(int cost, int value, int index, int id){int i = 0;for (i = cost; i <= v; ++i){if (dp[i] < dp[i - cost] + value){dp[i] = max(dp[i], dp[i - cost] + value);memcpy(path[i], path[i - cost], sizeof(path[i - cost]));path[i][index] = id;}}}void multiPacket(int cost, int value, int m,int index,  int id){if (m * cost >= v){completePacket(cost, value,index, id);return;}int k = 1;while(k <= m){zeroPacket(k * cost, k * value,index, id);m -= k;k *= 2;}if (m){zeroPacket(m * cost, m * value, index, id);}}int main(){int t, i, j, p, q, k;int sum = 0;int maxN = INT_MIN;path[0][0] = true;j = 0;int row;while (scanf("%d", &t) != EOF){memset(num, 0, sizeof(num));memset(dp, 0, sizeof(dp));memset(path, -1, sizeof(path));sum = 0;for (i = 0;i < t; ++i){scanf("%d", &arr[i].data);arr[i].index = i;sum += arr[i].data;if (maxN < arr[i].data){maxN = arr[i].data;}}int m = sum / maxN;for (p = m; p >= 2; --p){v = sum / p;q = 0;for (i = 0;i < p; ++i){vec[i].clear();}j = 0;do{memset(dp, 0, sizeof(dp));for (i = 0;i < t; ++i){if (arr[i].index != -1){multiPacket(arr[i].data, arr[i].data, 1, arr[i].index, q);}}if (dp[v] != v){break;}for (i = 0, k = 0;i < t; ++i){if (path[v][arr[i].index] == q){vec[j].push_back(arr[i].data); arr[i].index = -1;}}++j;row = j;}while(++q < p);if (q == p){for (i = 0;i < row;++i){for (j = 0; j < vec[i].size(); ++j){printf("%d ", vec[i][j]);}printf("\n");}break;}}if (q != p){for (i = 0;i < t; ++i){printf("%d ", arr[i].data);}printf("\n");}else{printf("\n");}}return 0;}


原创粉丝点击