- 注册时间
- 2007-12-26
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 539
- 在线时间
- 小时
|
发表于 2009-10-13 11:02:55
|
显示全部楼层
给出我的代码,效率比较低,采用动态规划做得
复杂度 O(sum * s1*s2)
原ACM题是将一数组化分为两数组, 使得他们和的差最小
同时两数组元素个数的差不超过1
#include
#include
#include
#include
using namespace std;
# define MAXN 100
# define MAXS 450
bitset<(MAXN + 1)*MAXS / 2> bs[MAXN / 2 + 1];
vector vec[MAXN /2 + 1];
// 4 1 2 4 10
int dp(int a[], int n)
{
std::sort(a + 1, a + n + 1);
if (n <= 2){
printf("%d %d\n", a[n - 1], a[n]);
return 0;
}
int sum = accumulate(a + 1, a + 1 + n, 0);
int minsum = a[1];
int maxlev = (n + 1) / 2;
bs[1].set(a[1]);
vec[1].push_back(a[1]);
for (int i = 2; i <= n; i++){
int curlev = min(i, maxlev); //update current curlev
for (int j = curlev - 1; j >= 0; j--){
for (int k = vec[j].size() - 1; k >= 0; k--){
int suma = vec[j][k] + a[i];
if (suma <= sum / 2 && !bs[j + 1].test(suma)){
if (j + 1 < maxlev){
bs[j + 1].set(suma);
vec[j + 1].push_back(suma);
}
if (suma > minsum){
if (j + 1 == maxlev && n % 2 == 0)
minsum = suma;
else if (j + 2 >= maxlev && n % 2 == 1)
minsum = suma;
if (minsum + 1 >= sum / 2)
break;
}
}
}
}
}
printf("%d %d\n", minsum, sum - minsum);
}
int main( )
{
int n;
int a[MAXN + 1] = {0};
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", a + i);
dp(a, n);
return 0;
} |
|