POJ 1014 dividing

来源:互联网 发布:ih5页面制作软件 编辑:程序博客网 时间:2024/06/10 10:15
      B - B
Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld & %llu
Submit Status Practice POJ 1014

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
 to 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.

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.

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,66种物品,输入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加进去是不需要再下面回溯的,如果先加到一个变量里,那下面回溯就要剪掉,我当时做的时候犯的错误;
  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;
}
1 0
原创粉丝点击