回溯法求解連續郵資問題

2021-09-24 07:14:50 字數 1210 閱讀 2217

內容:假設某國家發行了n中不同面值的郵票,並且規定每張信封上最多隻允許貼m張。

要求:對於給定的m和n的值,給出郵票面值的最佳設計,使得可以在一張信封上貼出從郵資1開始,增量為1的最大連續郵資區間。

①對於連續郵資的問題,由於實驗開始是僅給出面值的數量,而面值的具體值是未知的。但是由於郵資需要從1開始,因此,面值具體值中必然有1。可以考慮建立乙個陣列用於儲存具體的面值。x[1:n]表示從小到大儲存具體面值。

②當面值為1時,可形成的連續郵資區間為1~m,在此基礎上,若要增加面值,為保證區間連續,第二個面值必然要在2~m+1中取(第二個面值不能為1,並且若為m+2或者更大時,只用乙個就變為m+2,此時不連續),第三個面值則需要根據前兩個面值能達到的最大值來確定。第i個面值x[i]的連續區間若為1~r時,則第x[i+1]的個的取值必然為x[i]+1到r+1。則從第乙個面值開始,接下來的各個面值的取值都由上乙個面值以及能形成的最大值來取。

③但是為了求解最大連續區間,需要將面值的所有情況進行考慮,則對面值可能取值的語法樹進行遞迴遍歷,即回溯。遞迴到葉子節點時,將當前情況的最大值進行記錄並與之前的進行比較,若更大則儲存最大值,之後回溯到上一層繼續求解,直到將所有情況計算完成。

④為在第n層得到最大連續郵資區間,則在前幾層進行計算是,必須要達到即保證連續,又要保證每個郵資值盡量使用比較少的郵票張數,即多使用郵資大的郵票。這就要求每引進乙個新的郵票的時候,需要對當前郵資值陣列進行更新,以保證每個郵資值的達到使用的是最少的郵票數。

#include#define maxl 1000				//表示最大連續值 

#define maxint 32767

int n,m; //n為郵票種類數,m為能貼的最大張數

int maxvalue; //表示最大連續值

int bestx[100]; //表示最優解

int y[maxl]; //y[k],儲存表示到k值,所使用的最少郵票數

int x[100]; //儲存當前解

void backtrace(int i,int r);

int main()

for(int i=0;imaxvalue)

maxvalue = r-1;

} return;

} int z[maxl];

for(int k=0;kfor(int j=x[i]+1;j<=r;j++)

}

連續郵資問題 回溯法

需要注意的是 問題的解空間樹是虛擬的,並不需要在演算法執行時構造一棵真正的樹結構,只需要儲存從根節點到當前節點的路徑。假設某國家發行了n種不同面值的郵票,並且規定每張信封上最多隻允許貼m張郵票。連續郵資問題要求對於給定的n和m,給出郵票面值的最佳設計,在1張信封上貼出從郵資1開始,增量為1的最大連續...

連續郵資問題 回溯 動態規劃)

這個程式debug了好長時間.乙個晚上都耗上面了 這個程式實際上每一部分並不複雜,但是動態規劃那邊邊界錯了好長時間。題目 假設國家發行了n種不同面值的郵票,並且規定每張信封上最多隻允許貼m張郵票。連續郵資問題要求對於給定的n和m的值,給出郵票面值的最佳設計,在1張信封上可貼出從郵資1開始,增量為1的...

連續郵資問題

王曉東老師編著的 計算機演算法設計與分析 5.12 節以 連續郵資問題 為例展示了回溯法的應用。講解比較簡略,對於搜尋出一張新的郵票面值後如何更新最大連續郵資區間這一點沒有過多的說明。以下是自己對於這一節學習的一點筆記。實際上,關於剛才所說的更新最大連續郵資區間的方法,可以歸結到一種 等價類 的思想...