幸运的袋子
一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的)。如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积。
例如:如果袋子里面的球的号码是{1, 1, 2, 3},这个袋子就是幸运的,因为1 + 1 + 2 + 3 > 1 * 1 * 2 * 3
你可以适当从袋子里移除一些球(可以移除0个,但是别移除完),要使移除后的袋子是幸运的。现在让你编程计算一下你可以获得的多少种不同的幸运的袋子。
例如:如果袋子里面的球的号码是{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;
}
幸运袋子问题求解
本文介绍了一种通过编程解决数学组合问题的方法——幸运袋子问题。该问题要求在给定球的编号集合中,通过移除部分球使得剩余球的编号之和大于其乘积,并计算所有可能的幸运组合数量。
535

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



