【问题描述】
地产大亨Q先生临终的遗愿是:拿出100万元给X社区的居民抽奖,以稍慰藉心中愧疚。
麻烦的是,他有个很奇怪的要求:
1. 100万元必须被正好分成若干份(不能剩余)。
每份必须是7的若干次方元。
比如:1元, 7元,49元,343元,...
2. 相同金额的份数不能超过5份。
3. 在满足上述要求的情况下,分成的份数越多越好!
请你帮忙计算一下,最多可以分为多少份?
【问题分析】这个题目其实在我看来就是组合的问题,有重复项的问题,果然最近组合做多了,看什么都像组合……
其实,每份的金额满足是7的次方数的又小于100万的,也就几个{1 ,7 , 49,343 ,2401 ,16807 ,117649 ,823543}那么问题就很显然啦。就是每一个份额最多取五份,凑起来正好等于100万元的份数最多能分成多少份。最最最简单粗暴的就是暴力求解啊,也就八个循环嘛!分分钟出来!但是!毕竟我们要探求更好(其实也没好到哪去,就高级了一点)的方式。“AABBBC”中取3个字母的可能组合情况,就是一个典型的重复组合的题目,如果你这个还不知道的话,建议先看一下我的这一篇博客,花上一两个小时,把排列组合相关的学一学,加油!
https://blog.csdn.net/jfwzy109127/article/details/87801635
如果知道重复组合的问题,那么这个题目的递归函数就很轻松就出来了
void f(int a[],int x[],int k,int goal);
//a为每份的金额
//x为每份金额的数目
//k为当前考虑的位置
//goal 为当前目标的金额,初始值为100,0000
【代码】
#include <iostream>
using namespace std;
#define M 5 //最多四份
int count=0;
//a为每份的金额
//x为每份金额的数目
//k为当前考虑的位置
//goal 为当前目标的金额,初始值为100,0000
void f(int a[],int x[],int k,int goal){
if(k==8){
if(goal==0){
cout<<"第"<<++count<<"种情况:"<<endl;
for(int i=0;i<7;i++){
cout<<a[i]<<"\t"<<x[i]<<endl;
}
cout<<endl;
}
return;
}
for(int i=0;i<=M;i++){
x[k]=i;//试探
f(a,x,k+1,goal-i*a[k]);
x[k]=0;//回溯
}
}
int main(){
int a[8];
a[0]=1;
for(int i=1;i<8;i++){
a[i]=a[i-1]*7;
}
for(int i=0;i<8;i++){
cout<<a[i]<<'\t';
}
cout<<endl;
int x[8]={0};
f(a,x,0,1000000);
cout<<endl;
}
【最终代码运行结果】
第1种情况:
1 1
7 1
49 3
343 3
2401 3
16807 3
117649 1
就只有一种情况~~~~~~~~那么答案就是16啦!