幸运的袋子

来源:互联网 发布:finally java return 编辑:程序博客网 时间:2024/04/28 01:12
一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的)。如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积。
例如:如果袋子里面的球的号码是{1, 1, 2, 3},这个袋子就是幸运的,因为1 + 1 + 2 + 3 > 1 * 1 * 2 * 3

你可以适当从袋子里移除一些球(可以移除0个,但是别移除完),要使移除后的袋子是幸运的。现在让你编程计算一下你可以获得的多少种不同的幸运的袋子

这个问题还是用DFS深度优化探索来解决:

定义两个变量sum和multi,一个用于求和,一个用于求积

这里仍然要用到递归的思想

1.最小问题为,不满足这样的条件,直接退出

2.若满足,则继续往下探索:例如:

1 1 满足结论,就要继续探索1 1 2满足与否 1 1 2 满足要继续判断 1 1 2 3是否满足。

同时这些情况满足的时候计数结果cnt++,直到划为最小问题之后要重新判断1 2  和1 3的情况,所以必须恢复到之前的情况。

于是有这样一段程序:

sum-=a[i];
multi/=a[i];

3.1 1 2 3  中的1 1属于无区别的球号,所以要跳过

for(;i<n-1&&a[i]==a[i+1];++i);

但是有个问题就是输入可能是1 2 1 3,所以在此之前务必要进行排序

完整程序如下:

#include<iostream>  
#include <string> 
#include<algorithm>  
using namespace std;
const int N=10000;
int a[N];
int n;
int getnum(int a[],int pos,long sum,long multi)
{
    int cnt=0;
    for(int i=pos;i<n;i++)
    {
       sum+=a[i];
       multi *=a[i];
       if(sum>multi)  
         cnt+=1+getnum(a,i+1,sum,multi);
       else if(a[i]==1)//这里很重要
         cnt+=getnum(a,i+1,sum,multi);
       else//最小问题
          break;
       sum-=a[i];
       multi/=a[i];
       for(;i<n-1&&a[i]==a[i+1];++i);
    }
    return cnt;
}
int main(void)
{
   int count=0;
   while(scanf("%d",&n)>0)
   {
      for(int i=0;i<n;i++)
        {
          scanf("%d",&a[i]);
        }
        sort(a,a+n);
      count=getnum(a,0,0,1);
      printf("the number of the luggage is %d\n",count);
      return 0;
   }
   


原创粉丝点击