POJ 1014 dividing

  
  
  
B - B
Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld & %llu

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.

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,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加进去是不需要再下面回溯的,如果先加到一个变量里,那下面回溯就要剪掉,我当时做的时候犯的错误;
  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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Marcus-Bao

万水千山总是情,只给五角行不行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值