蓝桥杯——奇怪的捐赠

【问题描述】

地产大亨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啦!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值