网易2017内推笔试编程题合集(二)第二题 幸运的袋子

幸运袋子问题求解
本文介绍了一种通过编程解决数学组合问题的方法——幸运袋子问题。该问题要求在给定球的编号集合中,通过移除部分球使得剩余球的编号之和大于其乘积,并计算所有可能的幸运组合数量。


幸运的袋子
一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的)。如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积。
例如:如果袋子里面的球的号码是{1, 1, 2, 3},这个袋子就是幸运的,因为1 + 1 + 2 + 3 > 1 * 1 * 2 * 3
你可以适当从袋子里移除一些球(可以移除0个,但是别移除完),要使移除后的袋子是幸运的。现在让你编程计算一下你可以获得的多少种不同的幸运的袋子。 
输入描述:
第一行输入一个正整数n(n ≤ 1000)
第二行为n个数正整数xi(xi ≤ 1000)


输出描述:
输出可以产生的幸运的袋子数

输入例子:
3
1 1 1

输出例子:
2


#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 2000
int num[1001];
int dp[maxn];
int ans = 0;

void dfs(int start,int t,int s){
    //cout<<start<<" "<<t<<" "<<s<<endl;
    if(t >= maxn) return ;
    if(t >= s + num[1]) return ;
    ans += s + num[1] - t ;

    for(int i = start;i > 1; i--){
        if(num[i] == 0) continue;
        int x = t;
        for(int j = 1;j <= num[i] && x < maxn; j++){
            x *= i;
            dfs(min(i-1,maxn/x),x,s+i*j);
        }
    }
}

int main(){
    int n,u;
    cin>>n;
    memset(num,0,sizeof(num));
    for(int i = 0;i < n; i++){
        cin>>u;
        num[u]++;
    }
    memset(dp,0,sizeof(dp));
    ans = max(0,num[1] - 1);
    if(num[1] < 1){
        cout<<0<<endl;
        return 0;
    }
    for(int i = 2;i <= 1000; i++){
        int x = 1;
        for(int j = 1;j <= num[i] && x < maxn; j++){
            x *= i;
            dfs(min(i-1,maxn/i),x,i*j);
        }
    }
    cout<<ans<<endl;
}


评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GDRetop

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值