3213 - Number Partitioning Problem

Consider the partition problem: given a set S of n positive integers, partition it into two disjoint subsets S1 and S2 such that the discrepancy

                            E(S) = |sum(S1) - sum(S2)|

is minimized, where sum(Si) is the sum of Si's elements. Design an exhaustive search algorithm for this problem.

题目输入

Input includes multiple groups of data. The first line of each group of data is an integer n (10 <= n <= 20). n = 0 means that the input is over. Each of the next n lines has an integer which belongs to a set to be partitioned.

题目输出

For each test data, output the minimum discrepancy of two subsets into which the test data is partitioned.

输入/输出样例

题目输入

10
205
157
133
111
100
91
88
59
47
23
8
635
853
401
868
335
435
704
754
0

题目输出

0
3

提示

原样例数据超出范围,予以更新。

C语言解答

// test.cpp : 定义控制台应用程序的入口点。
//

#include <stdio.h>
#include <math.h>
long long S[20];

int bittest(unsigned int num, int bit)
{
	if ((num >> bit & 0x01) == 1)
		return 1;
	else
		return 0;
}

long long sum(long long s[20], unsigned int i, int n){
	long long t = 0;
	for (int j = 0; j < n; j++){
		if (bittest(i, j) == 1){
			t += s[j];
		}
	}
	return t;
}

long long subtract(long long t1,long long t2){
	if (t1>t2){
		return t1 - t2;
	}
	else{
		return t2 - t1;
	}
}

int main()
{
	int n;
	while (scanf("%d", &n) == 1 && n != 0){
		long long t = 0;
		for (int i = 0; i < n; i++){
			scanf("%ld", &S[i]);
			t += S[i];
		}
		for (unsigned int i = 0; i < (unsigned int)pow(2.0, n - 1); i++){
			long long r = subtract(sum(S, i, n), sum(S, ~i, n));
			if (t>r){
				t = r;
			}

		}
		printf("%lld\n", t);
	}
	return 0;
}

C++解答

// test.cpp : 定义控制台应用程序的入口点。
//

#include <stdio.h>
#include <math.h>
long long S[20];

int bittest(unsigned int num, int bit)
{
	if ((num >> bit & 0x01) == 1)
		return 1;
	else
		return 0;
}

long long sum(long long s[20], unsigned int i, int n){
	long long t = 0;
	for (int j = 0; j < n; j++){
		if (bittest(i, j) == 1){
			t += s[j];
		}
	}
	return t;
}

long long subtract(long long t1,long long t2){
	if (t1>t2){
		return t1 - t2;
	}
	else{
		return t2 - t1;
	}
}

int main()
{
	int n;
	while (scanf("%d", &n) == 1 && n != 0){
		long long t = 0;
		for (int i = 0; i < n; i++){
			scanf("%ld", &S[i]);
			t += S[i];
		}
		for (unsigned int i = 0; i < (unsigned int)pow(2.0, n - 1); i++){
			long long r = subtract(sum(S, i, n), sum(S, ~i, n));
			if (t>r){
				t = r;
			}

		}
		printf("%lld\n", t);
	}
	return 0;
}

提示

原样例数据超出范围,予以更新。

时间限制 10 秒
内存限制 128 MB
讨论 统计
上一题 下一题