積分組合問題

問題描述:給定一個積分總point,給定多個產品,每個產品需要相應數目的積分,用數組convertPoint[]表示,每種產品的兌換數量用數組convertCount[]表示,求如何兌換積分使得剩餘積分最少。

示例:

input:

point = 19

convertPoint[] = {5,3}

output:

convertCount[] = {2,3}

 

解題思路:

問題還是很清晰明瞭的,我們採用的思想也很粗暴,嘗試每一種組合方式,如 {0,0}, {0,1}, {0,2}, {0,3}...保證組合積分總數<=point即可,求得各種方案中剩餘積分數量最少的組合。

關鍵難點在於產品數目的可變性,無法用固定的多個循環體來描述問題,一般這時候就需要用到遞歸了。

 

直接看代碼:

	private static void calculateCash(int point,int i) {
        
        while(tempCount[i]*convertPoint[i]<=point){
        	if(i<convertPoint.length-1) {
        		calculateCash(point-tempCount[i]*convertPoint[i],i+1);
        	}else {
        		if((point-tempCount[i]*convertPoint[i])<rest) {
        			System.arraycopy(tempCount,0, convertCount, 0, tempCount.length);
        			rest = point-tempCount[i]*convertPoint[i];
        		}
        	}
        	tempCount[i]++;
        }
        tempCount[i] = 0;
    }

調用方法:

calculateCash(point,0);

需要兩個額外的輔助變量

1 int rest = convertPoint[0];   //表示最少的積分剩餘數

2 int tempCount[] = new int [convertPoint.length];   //用於表示目前的產品組合

 

優化:

對於最後一個產品數量可以不用從0開始向上加,直接取最大值;

即在此句if

if((point-tempCount[i]*convertPoint[i])<rest) {

前邊添加

tempCount[i] = point / convertPoint[i];

優化後代碼:

	private static void calculateCash(int point,int i) {
        
        while(tempCount[i]*convertPoint[i]<=point){
        	if(i<convertPoint.length-1) {
        		calculateCash(point-tempCount[i]*convertPoint[i],i+1);
        	}else {
        		tempCount[i] = point / convertPoint[i];
        		if((point-tempCount[i]*convertPoint[i])<rest) {
        			System.arraycopy(tempCount,0, convertCount, 0, tempCount.length);
        			rest = point-tempCount[i]*convertPoint[i];
        		}
        	}
        	tempCount[i]++;
        }
        tempCount[i] = 0;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章