又一次回顾了DFS的写法,感觉不错
在这里讲一下题意,免得以后自己再看时看不懂题目- -
有多种邮票,每种邮票有自己的价格,不同种的邮票价格可以一样
有多位顾客,每个顾客要在店里消费x元的邮票
计算每个顾客买邮票的最佳组合
最佳要求:
优先选种类最多组合
否则,优先数量最少的组合
否则,优先选“ 组合中面值最大邮票 ” 最大的组合
#include<stdio.h>
#include<string.h>
#include<math.h>
#define M 2000
int stamp[M],custom[M],stamp_num,custom_num,ans,put[M],flag;
int now_custom;
int best_n,best_z,best_max,best_put[M];
void change_best(int n,int z)
{
int i;
best_z=z;
best_max=stamp[put[n-1]];
best_n=n;
for(i=0;i<n;i++)
best_put[i]=put[i];
flag=0;
}
int dfs(int n,int sum,int z,int j)
{
int i;
if(n>4)
return ;
if(sum==now_custom)
{
if(z>best_z)
change_best(n,z);
else if(z==best_z)
{
if(n<best_n)
change_best(n,z);
else if(n==best_n)
{
if(stamp[put[n-1]]>best_max)
change_best(n,z);
else if(stamp[put[n-1]]==best_max)
flag=1;
}
}
return ;
}
for(i=j;i<stamp_num;i++)
{
put[n]=i;
if(n==0||put[n]!=put[n-1])
z=z+1;
dfs(n+1,sum+stamp[i],z,i);
if(n==0||put[n]!=put[n-1])
z=z-1;
}
}
void sort(int ii)
{
int i,j;
int temp;
for(i=0;i<ii;i++)
for(j=i;j<ii;j++)
{
if(stamp[i]>stamp[j])
{
temp=stamp[j];
stamp[j]=stamp[i];
stamp[i]=temp;
}
}
}
void main()
{
int i,j,a;
while(scanf("%d",&a)!=EOF)
{
i=0;
stamp[i]=a;
i++;
while(scanf("%d",&a),a!=0)
{
stamp[i]=a;
i++;
}
sort(i);
stamp_num=i;
i=0;
while(scanf("%d",&a),a!=0)
{
custom[i]=a;
i++;
}
custom_num=i;
for(i=0;i<custom_num;i++)
{
best_max=best_z=best_n=0;
flag=2;
now_custom=custom[i];
dfs(0,0,0,0);
if(flag==0)
{
printf("%d (%d):",custom[i],best_z);
for(j=0;j<best_n;j++)
{
printf(" %d",stamp[best_put[j]]);
}
printf("\n");
}
else if(flag==1)
{
printf("%d (%d):",custom[i],best_z);
printf(" tie\n");
}
else if(flag==2)
{
printf("%d ---- none\n",custom[i]);
}
}
}
}