4 回答
TA貢獻1789條經驗 獲得超8個贊
var cnt = 0;
function change(target, coins, usable) {
let coin = coins.shift();//應該要給coin聲明變量,不聲明會默認全局變量則導致下面for循環的值跟著變動,就一直不滿足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);//這里應該復制一份coins,避免遞歸時候使用shift把數據給修改了.
}
}
}
change(1000, [500, 100, 50, 10], 15);
console.log(cnt);
TA貢獻1865條經驗 獲得超7個贊
既然是算法題,就應該先考慮算法
其實這個問題轉化后就是求 有4個不同的數字在數組A中,抽取每個數字(允許多次抽?。┛偝槿滴籒(N<=15),使得其總和等于X,問有多少可能(最少可能是0個,即不能匹配抽?。?/p>
當然,因為這個題中X和A已經確定了,所以可以減少搜索規模。
前面給出了一種方法,我想用另外一種方法求解(位運算)
根據前面的一些條件,其實可能可以映射到一個2bit(最大值為3)+4bit(最大值為15)+4bit(最大值為15)+4bit(最大值為15) 是數字上
其中2bit對應于500的數量,因為剛好等于2的可能是唯一的,所以可以退化為1bit+4bit+4bit+4bit的數字上(一共13bit)
且各段數據總和小于等于15,第二段也要小于等于10,所以遍歷符合條件的數字,就可以獲取最終結果了。下面是實現(這個題對這個來說不是最優解,但如果A數據量擴大,N擴大和X擴大,則可能是較優解,因為只是單純的遍歷了,是O(N)復雜度算法),且這個算法實現邏輯也比較簡單,語句也比較簡單。
var A=[500,100,50,10];//
var RT=[[2,0,0,0]];//存儲最終結果
var s=0x1AFF; //起始數據
for(;s>0;s--){
//提取各個的系數
a0=s>>12;
a1=(s>>8)&0xf;
a2=(s>>4)&0xf;
a3=s&0xf;
if(a1>10 || a0+a1+a2+a3>15) continue; // 過濾掉不符合系數條件的
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);//輸出可能數量
添加回答
舉報
