首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

zju 2868 求剪枝方法解决方法

2012-03-26 
zju 2868求剪枝方法http://acm.zju.edu.cn/show_problem.php?pid2868用的是0_1 搜索(就是选与不选), 加上

zju 2868 求剪枝方法
http://acm.zju.edu.cn/show_problem.php?pid=2868

用的是0_1 搜索(就是选与不选), 加上一点剪枝,只是剪得不好,结果超时了,想知道怎么剪更好。

#include "stdio.h"
#include "stdlib.h"

int teamA,teamB;
int min;
int sum;
int arry[50];

int cmp(void const * a,void const *b)
{
return *((int *)b)-*((int *)a);
}


void Select(int step,int n)
{
if(step>n)
{
if( abs(teamA-teamB) < min )
min=abs(teamA-teamB);
return;
}

if(2*teamA-sum > min)
return;
if(2*teamB-sum>min)
return ;

teamA+=arry[step];
Select(step+1,n);
teamA-=arry[step];

teamB+=arry[step];
Select(step+1,n);
teamB-=arry[step];
}

int main()
{
int cas,n;
int i;

scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
min=0;sum=0;

for(i=0;i<n;i++)
{
scanf("%d",&arry[i]);
sum+=arry[i];

}

qsort(arry,n,sizeof(int),cmp);

teamA=teamB=0;
for(i=0;i<n;i++)
{
if(teamA>=teamB)
teamB+=arry[i];
else
teamA+=arry[i];
}
min=abs(teamA-teamB);

teamA=arry[0];teamB=0;
Select(1,n);
printf("%d\n",min);
}
return 0;
}

[解决办法]
2665800 2007-11-02 12:09:44 Accepted 2868 C 00:00.87 1560K tailzhou 

#include <stdio.h>
#include <stdlib.h> 

#define MAX_LEN 34

int num[MAX_LEN];

int diff1[0x1<<17];
int diff2[0x1<<17];


int cmp(void const * a,void const *b) 

return *((int *)b)-*((int *)a); 


int main()
{
int t;

scanf("%d", &t);
while (t--)
{
int n;
int i,j,k;
int sum1=0,sum2=0,min_diff;
scanf("%d", &n);
i=0;
while (i<n)
{
scanf("%d", num+i);
if (i<n/2) sum1+=num[i];
else sum2+=num[i];
i++;
}

for (i=0;i<(0x1<<(n/2)) ; i++)
{
int tmp=0;
j=i;
k=0;
while (j>0)
{
if (j & 0x1) tmp+=num[k];
k++;
j>>=1;
}
diff1[i]=abs(sum1-2*tmp);
}

for (i=0;i<(0x1<<(n-n/2)) ; i++)
{
int tmp=0;
j=i;
k=0;
while (j>0)
{
if (j & 0x1) tmp+=num[k+n/2];
k++;
j>>=1;
}
diff2[i]=abs(sum2-2*tmp);
}

qsort(diff1,0x1<<(n/2),sizeof(int),cmp); 
qsort(diff2,0x1<<(n-n/2),sizeof(int),cmp);

min_diff=abs(diff1[0]-diff2[0] );
i=j=0;
while (i<0x1<<(n/2) && j<0x1<<(n-n/2))
{
while (j<0x1<<(n-n/2) && diff2[j]>diff1[i]) j++;
if (j>0 && abs(diff2[j-1]-diff1[i])<min_diff) min_diff=abs(diff2[j-1]-diff1[i]);
if (j<0x1<<(n-n/2) && abs(diff2[j]-diff1[i])<min_diff) min_diff=abs(diff2[j]-diff1[i]);
if (min_diff==0) 
{
break;
}
i++;
}
printf("%d\n",min_diff);
}

return 0;
}

热点排行