石子合并
(stone.pas/in/out)
Problem
你有一堆石头质量分别为W1,W2,W3...WN.(W<=100000)现在需要你将石头合并为两堆,使两堆质量的差为最小。
Input
该程序有多组测试数据,每组测试数据第一行为整数N(1<=N<=20),表示有N堆石子。接下去N行,为每堆石子的质量。
Output
每组测试数据只需输出合并后两堆的质量差的最小值。
Sample Input
5
5
8
13
27
14
2
4
4
Sample Output
3
0
分析:
其实此题和真正的石子合并没有什么关系,要看真正的石子合并的见: 石子合并 解题报告
其实这题就是一个背包,把一堆石子的和当状态,另一堆当值求01背包即可。
我的程序:
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
int n,a[100];
int f[2001000],maxn,now,ans;
void solve()
{
int i,j;
while (scanf("%d\n",&n)!=EOF)
{
memset(a,0,sizeof(a));
for (i=1;i<=n;i++)
scanf("%d\n",&a[i]);
memset(f,255,sizeof(f));
now=a[1];
ans=0x7fffffff;
for (i=1;i<=n;i++)
{
maxn=now;
now=0;
for (j=maxn;j>=0;j--)
if (f[j]!=-1)
{
f[j+a[i]]=f[j];
if (j+a[i]>now) now=j+a[i];
if (i==n) if (ans>abs(j+a[i]-f[j])) ans=abs(j+a[i]-f[j]);
f[j]+=a[i];
if (i==n)if (ans>abs(j-f[j])) ans=abs(j-f[j]);
}
}
printf("%d\n",ans);
}
}
int main(int argc, char *argv[])
{
freopen("stone.in","r",stdin);
freopen("stone.out","w",stdout);
solve();
return 0;