var cnt = 0;
function change(target, coins, usable) {
coin = coins.shift();
if(coins.length==0) {
if(target/coin<=usable) {
cnt += 1;
}
}
else{
for(let i=0; i<=target/coin; i++) {
change(target-coin*i, coins, usable-i);
}
}
}
change(1000, [500, 100, 50, 10], 15);
console.log(cnt);
算法題目鏈接:https://max.book118.com/html/...。
題目:當下,坐公交或者地鐵時大部分人都是刷卡的。不過,時至今日還在用現(xiàn)金支付的人還是比想象的多。本題我們以安置在公交上的零錢兌換機為背景。
這個機器可以用紙幣兌換到 10 日元、50 日元、100 日元和 500 日元硬幣的組合,且每種硬幣的數(shù)量都足夠多(因為公交接受的最小額度為 10 日元,所以不提供 1 日元和 5 日元的硬幣)。
兌換時,允許機器兌換出本次支付時用不到的硬幣。此外,因為在乘坐公交時,如果兌換出了大量的零錢會比較不便,所以只允許機器最多兌換出 15 枚硬幣。譬如用 1000 日元紙幣兌換時,就不能兌換出“100 枚 10 日元硬幣”的組合。
求兌換 1000 日元紙幣時會出現(xiàn)多少種組合?注意,不計硬幣兌出的先后順序。
既然是算法題,就應(yīng)該先考慮算法
其實這個問題轉(zhuǎn)化后就是求 有4個不同的數(shù)字在數(shù)組A中,抽取每個數(shù)字(允許多次抽取)總抽取數(shù)位N(N<=15),使得其總和等于X,問有多少可能(最少可能是0個,即不能匹配抽?。?br>當然,因為這個題中X和A已經(jīng)確定了,所以可以減少搜索規(guī)模。
前面給出了一種方法,我想用另外一種方法求解(位運算)
根據(jù)前面的一些條件,其實可能可以映射到一個2bit(最大值為3)+4bit(最大值為15)+4bit(最大值為15)+4bit(最大值為15) 是數(shù)字上
其中2bit對應(yīng)于500的數(shù)量,因為剛好等于2的可能是唯一的,所以可以退化為1bit+4bit+4bit+4bit的數(shù)字上(一共13bit)
且各段數(shù)據(jù)總和小于等于15,第二段也要小于等于10,所以遍歷符合條件的數(shù)字,就可以獲取最終結(jié)果了。下面是實現(xiàn)(這個題對這個來說不是最優(yōu)解,但如果A數(shù)據(jù)量擴大,N擴大和X擴大,則可能是較優(yōu)解,因為只是單純的遍歷了,是O(N)復(fù)雜度算法),且這個算法實現(xiàn)邏輯也比較簡單,語句也比較簡單。
var A=[500,100,50,10];//
var RT=[[2,0,0,0]];//存儲最終結(jié)果
var s=0x1AFF; //起始數(shù)據(jù)
for(;s>0;s--){
//提取各個的系數(shù)
a0=s>>12;
a1=(s>>8)&0xf;
a2=(s>>4)&0xf;
a3=s&0xf;
if(a1>10 || a0+a1+a2+a3>15) continue; // 過濾掉不符合系數(shù)條件的
if(a0*A[0]+a1*A[1]+a2*A[2]+a3*A[3] ===1000) RT.push([a0,a1,a2,a3]);
}
console.log(RT);
var cnt=RT.length;
console.log(cnt);//輸出可能數(shù)量竟然是個算法題,
你這個鏈接我打不開,無奈臉.gif
我的答案
var cnt = 0, pagerCoin = 1000;
//
// 假設(shè)有 a枚500 b枚100 c枚50 d枚10
// 現(xiàn)在要求 a+b+c+d <=15
// 500a+100b+50c+10d = 1000
// 獲取其中一枚硬幣可以兌換的數(shù)量
function getOneCoinsMaxNumber(pagerCoin,coin){
return Math.floor(pagerCoin/coin)
}
let abcd = [];
// 枚舉出當前紙幣可以兌換的 abcd可能的值
for(let at,ai = (at=getOneCoinsMaxNumber(pagerCoin, 500)) > 15 ? 15 : at; ai >= 0; ai--)
for(let bt,bi = (bt=getOneCoinsMaxNumber(pagerCoin,100)) > 15 ? 15 : bt; bi >= 0; bi--)
for(let ct,ci = (ct=getOneCoinsMaxNumber(pagerCoin,50)) > 15 ? 15 : ct; ci >= 0; ci--)
for(let dt,di = (dt=getOneCoinsMaxNumber(pagerCoin,10)) > 15 ? 15 : dt; di >= 0; di--)
console.log(ai,bi,ci,di,abcd.push([ai,bi,ci,di]))
// abcd中就是枚舉到的所有值了
console.log(abcd)
let coins = [500,100,50,10]
// 依據(jù)我們的假設(shè) 我們有倆個條件需要滿足,才符合兌換要求
let rule1 = arr => arr.reduce((init,item) => init+=item,0)
let rule2 = arr => arr[0]*coins[0]+arr[1]*coins[1]+arr[2]*coins[2]+arr[3]*coins[3]
// 對枚舉的值進行過濾,獲取符合要求的
let d =abcd.filter(item => rule1(item) <= 15 && rule2(item) == 1000)
console.log(d);
結(jié)果如下:這個方法比較粗糙,先貼上來,給你個參考,你那個方式你沒有解釋和注釋,所以理解起來比較吃力,所以沒有有看下去。
var cnt = 0;
function change(target, coins, usable) {
let coin = coins.shift();//應(yīng)該要給coin聲明變量,不聲明會默認全局變量則導(dǎo)致下面for循環(huán)的值跟著變動,就一直不滿足target/coin<=usable的條件.
if(coins.length==0) {
if(target/coin<=usable) {
cnt += 1;
}
}
else{
for(let i=0; i<=target/coin; i++) {
change(target-coin*i, coins.slice(), usable-i);//這里應(yīng)該復(fù)制一份coins,避免遞歸時候使用shift把數(shù)據(jù)給修改了.
}
}
}
change(1000, [500, 100, 50, 10], 15);
console.log(cnt);北大青鳥APTECH成立于1999年。依托北京大學優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達內(nèi)教育集團成立于2002年,是一家由留學海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進“中國制造2025”,實現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責任公司從事總經(jīng)理職務(wù)負責iOS教學及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風格 授課風格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。