Description
Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbles.
This would be easy if all the marbles had the same value, because then they could just split the collection in half. But unfortunately, some of the
marbles are larger, or more beautiful than others. So, Marsha and Bill start by assigning a value, a natural number between one and six, to each
marble. Now they want to divide the marbles so that each of them gets the same total value. Unfortunately, they realize that it might be impossible
t
o divide the marbles in this way (even if the total value of all marbles is even). For example, if there are one marble of value 1, one of value 3 and
two of value 4, then they cannot be split into sets of equal value. So, they ask you to write a program that checks whether there is a fair partition
of the marbles.
Input
Each line in the input file describes one collection of marbles to be divided. The lines contain six non-negative integers n1 , . . . , n6 , where ni is the
number of marbles of value i. So, the example from above would be described by the input-line "1 0 1 2 0 0". The maximum total number of marbles
will be 20000.
The last line of the input file will be "0 0 0 0 0 0"; do not process this line.
The last line of the input file will be "0 0 0 0 0 0"; do not process this line.
Output
For each collection, output "Collection #k:", where k is the number of the test case, and then either "Can be divided." or "Can't be divided.".
Output a blank line after each test case.
Output a blank line after each test case.
Sample Input
1 0 1 2 0 0 1 0 0 0 1 1 0 0 0 0 0 0
Sample Output
Collection #1: Can't be divided. Collection #2: Can be divided.
题意:
有分别价值为
1,2,3,4,5,6
的
6
种物品,输入
6
个数字,表示相应价值的物品的数量,问一下能不能将物品分成两份,是两份的
总价值相等,其中一个物品不能切开,只能分给其中的某一方,当输入六个
0
是(即没有物品了),这程序结束,总物品的
总个数不超过
20000
思路:这个题真的让我充分理解了dfs,因为这个题就6个数据,数据量又不大,我们dfs也可以过的;
这里我们先将所有物品的价值求和,如果所有的和为奇数,那么肯定就不能分,直接输出就好;
如果总和为偶数,那么我们就dfs,在dfs中,我每次都从最大的开始dfs(因为从最大的来搜索可以大大降低递归的次数,你想啊
对于一半的长度,我们每次先用大的填,超了换小一点的去补,和每次从小的开始去填,然后大的没用到,再继续找,直到给定长度,
肯定是长的搜索的范围大,次数少,通俗一点的理解法。。。。)如果使用此物品,数量就--,直到价值恰好等于总价值的一半
结束即可;
#include<stdio.h>
#include<string.h>
int num[10];
int sum,flag;
void dfs(int s,int l)
{ if(s==sum/2)
{ flag=1;
return ;
}
if(flag)
return ;
for(int i=l;i>0;i--)
{ if(num[i])
{
if(s+i<=sum/2)
{ num[i]--;
dfs(s+i,i);//这里如果直接将i加进去是不需要再下面回溯的,如果先加到一个变量里,那下面回溯就要剪掉,我当时做的时候犯的错误;
#include<string.h>
int num[10];
int sum,flag;
void dfs(int s,int l)
{ if(s==sum/2)
{ flag=1;
return ;
}
if(flag)
return ;
for(int i=l;i>0;i--)
{ if(num[i])
{
if(s+i<=sum/2)
{ num[i]--;
dfs(s+i,i);//这里如果直接将i加进去是不需要再下面回溯的,如果先加到一个变量里,那下面回溯就要剪掉,我当时做的时候犯的错误;
if(flag==1)
return ;
}
}
}
return ;
}
int main()
{ int i;
int k=1;
while(scanf("%d %d %d %d %d %d",&num[1],&num[2],&num[3],&num[4],&num[5],&num[6])!=EOF)
{
if(num[1]+num[2]+num[3]+num[4]+num[5]+num[6]==0)
break;
sum=0;
flag=0;
for(i=1;i<7;i++)
sum=sum+i*num[i];
//printf("%d\n",sum);
printf("Collection #%d:\n",k++);
if(sum%2)
printf("Can't be divided.\n");
else
{ dfs(0,6);
if(flag)
printf("Can be divided.\n");
else
printf("Can't be divided.\n");
}
printf("\n");
}
return 0;
}
return ;
}
}
}
return ;
}
int main()
{ int i;
int k=1;
while(scanf("%d %d %d %d %d %d",&num[1],&num[2],&num[3],&num[4],&num[5],&num[6])!=EOF)
{
if(num[1]+num[2]+num[3]+num[4]+num[5]+num[6]==0)
break;
sum=0;
flag=0;
for(i=1;i<7;i++)
sum=sum+i*num[i];
//printf("%d\n",sum);
printf("Collection #%d:\n",k++);
if(sum%2)
printf("Can't be divided.\n");
else
{ dfs(0,6);
if(flag)
printf("Can be divided.\n");
else
printf("Can't be divided.\n");
}
printf("\n");
}
return 0;
}

430

被折叠的 条评论
为什么被折叠?



