题目链接:
http://acm.nyist.net/JudgeOnline/problem.php?pid=325
这个题用搜索和01背包都可以做,但是01背包超时了( ▼-▼ )
1.
常规搜索(时间有点长):
#include
#include
#include
#include
using namespace std;
int minn,sum;
int a[100];
void dfs(int m,int i,int cur)
{
if(iint tmp=sum-cur*2; //tmp的绝对值表示差值;
if(tmp<0)tmp=-tmp;
if(tmp1,cur+a[i+1]);
dfs(m,i+1,cur);
}
return ;
}
int main()
{
int m;
while(scanf("%d",&m)!=EOF)
{
sum=0;
memset(a,0,sizeof(a));
for(int i=0;iscanf("%d",&a[i]);
sum+=a[i];
}
minn=sum;
dfs(m,0,a[0]);
printf("%d\n",minn);
}
return 0;
}
2.
高效搜索:
#include
#include
#include
using namespace std;
#define max(a,b) a>b?a:b
int V, ans, n, w[21], sum[21];
void dfs(int i,int cnt)
{
if(i == 0)
{
ans = max(ans,cnt);
return ;
}
if(ans == V || cnt+sum[i] <= ans)
return ;
if(cnt+w[i] <= V)
dfs(i-1,cnt+w[i]);//前一个放
dfs(i-1,cnt); //前一个不放
}
int main()
{
while(scanf("%d",&n) != EOF)
{
ans = 0;
memset(w, sizeof(w), 0);
memset(sum, sizeof(sum), 0);
for(int i=1;i<=n;i++)
{
scanf("%d",&w[i]);
sum[i] = sum[i-1] + w[i];
}
V = sum[n]/2; //只搜一半
dfs(n,0);
printf("%d\n",sum[n]-2*ans);
}
return 0;
}
3.
01背包做法(超时):
#include
#include
#include
#include
#include
#include
using namespace std;
int sum;
int b[20005];
int a[100];
int main()
{
int m;
while(scanf("%d",&m)!=EOF)
{
sum=0;
memset(b,0,sizeof(b));
for(int i=0;iscanf("%d",&a[i]);
sum+=a[i];
}
for(int i=0;ifor(int j=sum/2;j>=a[i];j--)//用一半容积
{
b[j]=max(b[j],b[j-a[i]]+a[i]);
}
}
printf("%d\n",sum-2*b[sum/2]);
}
return 0;
}
PhotoBy:WLOP
http://weibo.com/wlop