先說一下業務背景。公司作的一個投資的APP,投資金額能夠用優惠券抵扣。紅包面額(100,50,30,10)php
前面三個均可以經過數據庫檢索排序實現生成一個數組,最後一個就要使用程序算法實現了。
一開始有想過揹包法、窮舉法。算法
算出用戶本次投資最大使用優惠券總額(redAmount)、獲取用戶的優惠券列表(redCoupons)(已按前三規則排序)直接上代碼:數據庫
public function dealCoupon() { $redCoupons =[]; $restRedAmount = 100; $redCouponIdLists = []; $restRedAmounts = []; $arrCount = count($redCoupons); for ($i=0; $i<$arrCount; $i++) { list($redCouponIdList, $restRedAmount) = getBestCoupon($redCoupons, $restRedAmount); if ($restRedAmount == 0) { $bestCouponIdList = $redCouponIdList; break; } $redCouponIdLists[] = $redCouponIdList; $restRedAmounts[] = $restRedAmount; array_shift($redCoupons); } if (empty($bestCouponIdList)) { $pos = array_search(min($restRedAmounts), $restRedAmounts); $bestCouponIdList = $redCouponIdLists[$pos]; } } /** * 紅包最優算法 */ private function getBestCoupon($redCoupons, $restRedAmount) { $redCouponAmount = 0; foreach ($redCoupons as $redCoupon) { if ($restRedAmount >= $redCoupon->getAmount()) { $redCouponAmount = $redCouponAmount + $redCoupon->getAmount()); $redCouponIdList[] = $redCoupon->getCouponId(); $restRedAmount = $restRedAmount - $redCoupon->getAmount(); if ($restRedAmount == 0) break; } } return [$redCouponIdList, $restRedAmount]; }