這個程式debug了好長時間....乙個晚上都耗上面了
這個程式實際上每一部分並不複雜,但是動態規劃那邊邊界錯了好長時間。
題目:假設國家發行了n種不同面值的郵票,並且規定每張信封上最多隻允許貼m張郵票。連續郵資問題要求對於給定的n和m的值,給出郵票面值的最佳設計,在1張信封上可貼出從郵資1開始,增量為1的最大連續郵資區間。例如,當n=5和m=4時,面值為(1,3,11,15,32)的5種郵票可以貼出郵資的最大連續郵資區間是1到70。
首先比較困難的這個題目看上去迴圈是沒有上限的,也就是我們看似找不到迴圈邊界,其實我們只需考慮可能生成的節點即可。
dfs(x,cur,max)其中x陣列儲存當前的解有哪些(如果你就是求具體數值,而不要求解的組成甚至可以省略),cur代表目前到第幾種面值,當到n為止,max表示到目前為止的最大可到達郵資,而之後下乙個x[cur+1]一定是取x[cur]+1~max+1,這個很好理解,max+1目前是訪問不到的,那麼我加入x[cur+1]後,要看看max更新到多少,而max是從max+1到
m*x[cur+1](最多就是m個最大的那個郵票,最少肯定是要更新,不然要你何用...),接下來的問題就是能否用n種郵票,面值都儲存在x陣列中,最多貼m張,表示出某個數,
方法是動態規劃,狀態轉移方程dp[i,j]=min(dp[i-1][j-k*a[i]+k),其實有點像揹包;(注意邊界!!!!!!!)dp[i][0]=0(沒有錢時0張郵票)dp[1][i]=i;(因為第一張郵票就是1,貼幾塊錢就是幾張郵票)
話說我的程式跑的真慢,應該還能優化...
附一些資料
n= 5 m=4 最大郵資為70
n=5 m=5 最大郵資為126
n=4 m=2 最大郵資為12
n=3 m=4 最大郵資為26
n=6 m=4最大郵資為108
n=5 m=6最大郵資為216
#include #include int n,m;//n為郵票種類,m為一封信上最多貼的郵票個數
int max;
int ans[10000];//最終答案陣列
int min(int a,int b)
void dfs(int x[10000],int cur,int max)
return;
}for (next=x[cur]+1;next<=max+1;next++)//如果還沒得到n中郵票,那麼從x[cur]+1~max+1選乙個作為下乙個郵資,因為max+1沒法表示,所以必定到max+1為止
} int main()
連續郵資問題 回溯法
需要注意的是 問題的解空間樹是虛擬的,並不需要在演算法執行時構造一棵真正的樹結構,只需要儲存從根節點到當前節點的路徑。假設某國家發行了n種不同面值的郵票,並且規定每張信封上最多隻允許貼m張郵票。連續郵資問題要求對於給定的n和m,給出郵票面值的最佳設計,在1張信封上貼出從郵資1開始,增量為1的最大連續...
回溯法求解連續郵資問題
內容 假設某國家發行了n中不同面值的郵票,並且規定每張信封上最多隻允許貼m張。要求 對於給定的m和n的值,給出郵票面值的最佳設計,使得可以在一張信封上貼出從郵資1開始,增量為1的最大連續郵資區間。對於連續郵資的問題,由於實驗開始是僅給出面值的數量,而面值的具體值是未知的。但是由於郵資需要從1開始,因...
連續郵資問題
王曉東老師編著的 計算機演算法設計與分析 5.12 節以 連續郵資問題 為例展示了回溯法的應用。講解比較簡略,對於搜尋出一張新的郵票面值後如何更新最大連續郵資區間這一點沒有過多的說明。以下是自己對於這一節學習的一點筆記。實際上,關於剛才所說的更新最大連續郵資區間的方法,可以歸結到一種 等價類 的思想...