蓝桥杯——奇怪的捐赠

时间:2019-02-20
本文章向大家介绍蓝桥杯——奇怪的捐赠,主要包括蓝桥杯——奇怪的捐赠使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

【问题描述】

地产大亨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;
}