正整数被指定正整数队列拆分算法,最大拆除法(java)

       近期由于公司搞话费充值活动,话费都是三网有固定额度,例如面额 100,50,30,20,10,1-9 等等(有时可能移动,电信能充值这些面额,联通可能充不了20,10,1-9)。用户在充值操作中,有时是个性化的充值,例如充值60,160,165等,那么问题来了,要根据手机号运营商找到对应面额,进行最大拆分。

       *先解释下个人理解的最大拆分,例如160元的拆分有多种,例如(100,50,10)(160个1元)(100,30,30)之类,其中(100,50,10)是叫做最大拆分(这个涉及成本问题,面额大的优惠力度也大)。

       现在正题来了,经过无数次算法的研究和计算,最终应用树递归左遍历模式,进行计算。先上个图

       例如,把160 根据  [100,50,30,10] 进行最大拆分

       

      图中可见,

      1)除根节点外,每个节点的分支都是小于该节点数值的剩余队列。

      2)根据树结构左遍历方式,会先找到100剩余60,60再继续找到50剩余10,10继续找到30,无法继续,回溯到同层10,发现正好整除,既遍历结束,最大拆分组被找到。

       代码献上

       方法代码:

public static boolean getFeeList2(List<Integer> myFeeList,int myFee,List<Integer> feeList){

		for (Integer fee : feeList) {
			//先判断充值额度是否大于面额度,不能下一个面额
			if(myFee<fee){
				continue;
			}
			//计算整除数和余数
			int zct = myFee/fee;
			int yt = myFee%fee;
			if(yt==0){//余数为0,代表正好能整除,则到了根节点

				for(int i=0;i<zct;i++){
					myFeeList.add(fee);
				}
				return true;
			}else{//余数不为0

				//递归出口,判断是否为叶子节点,是返回
				if(feeList.size()==1){
					return false;
				}
				//获取该节点子节点序列
				List<Integer> subList = feeList.subList(1, feeList.size());
				//求出剩余充值额度
				int bFee=myFee-fee;
				//再次往下遍历树结构
				boolean feeList2 = getFeeList2(myFeeList, bFee, subList);
				if(feeList2){
					myFeeList.add(fee);
					return true;
				}else{
					continue;
				}
			}
		}
		return false;
	}

 测试代码:

  

	public static void main(String[] args) {

		//最终拆分组
		List<Integer> myFeeList = new ArrayList<Integer>();

		//面值
		List<Integer> feelist = new ArrayList<Integer>();
		feelist.add(100);
		feelist.add(50);
		feelist.add(30);
		feelist.add(10);
		feelist.add(6);
		feelist.add(1);
		
		//充值额度
		int myFee=160;

		//寻找最大拆分组,如果能拆分返回true,不能拆分返回false
		boolean feeList2 = BillFileUtils.getFeeList2(myFeeList, myFee, feelist);
		System.out.println(feeList2);
		//能拆分打印拆分后的队列
		for (Integer integer : myFeeList) {
			System.out.println(integer);
		}
    }

测试结果图:(160)

测试结果图:(60)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

muziyouyouli

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

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

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

打赏作者

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

抵扣说明:

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

余额充值