1. 程式人生 > >演算法導論鋼條切割問題

演算法導論鋼條切割問題

鋼條切割

思路:
1、先考慮,鋼條總長度為0時,總價值為02、考慮,鋼條總長度為1時,此時無法切割,總價值為13、鋼條長為2時,兩種情況:不切割,中間切割一次,比較誰大,取大的方案(要用到上面的結果2);
...
總結:長度為i的鋼條,最左端切割的位置為k,那麼總價值如下遞推式:

dp[i] = max(dp[i−k]+price[k])(i>0,1<= k<=i )
dp[0] = 0(i=0)

#include <iostream>

using namespace std;

int price[11] = {0,1,5,8,9,10,17,17,20
,24,30}; int N = 10; int a[11]; int solution2(int m){ int dp[11]; int ans = 0; // memset(dp,0, sizeof(dp)); dp[0] = 0; for (int i = 1; i <= m; ++i) { for (int j = 1; j <= i; ++j) { // dp[i] = max(dp[i],price[j]+dp[i-j]); ans = max(ans,price[j]+dp[i-j]); } dp[i] = ans; } return
dp[m]; } int solution(int i,int j){ int ans = 0; if(i >= j) return 0; else{ // ans = price[j-i];//此處為什麼要單獨拿出來寫??? //上面這句是第一次寫錯了,下面的迴圈寫的是k = i,導致遞迴會一直在solution(i,j)上無線死迴圈。然後加了上面的句子處理初始情況,把下面k從i+1開始,其實上面的句子就是k = j時的特例,不需要單獨拿出來 for (int k = i+1; k <= j; ++k) { ans = max(ans,price[k-i] + solution(k,j)); // return ans;
} return ans;//由於之前把這個地方寫錯了,導致很多錯誤不能理解 } } //此處是用的長度做遞迴引數,由此也能引發思考,明顯使用長度做引數程式碼要好寫,考慮的東西也更少! int solution1(int n){ // int ans = 0; if(a[n] > 0) return a[n]; if(n == 0) return 0; else{ // ans = price[n]; for (int k = 1; k <= n; ++k) { a[n] = max(a[n],price[k] + solution1(n-k)); // return ans; } return a[n]; } } /* * output: 第一種解法: 1 5 8 10 13 17 18 22 25 30 第二種解法: 1 5 8 10 13 17 18 22 25 30 第三種解法: 1 5 8 10 13 17 18 22 25 30 */ int main() { cout << "第一種解法: " << endl; for (int j = 2; j <= 11; ++j) { cout << solution(1,j) << " "; } cout << endl << "第二種解法: " << endl; for (int i = 1; i <= 10; ++i) { memset(a,0, sizeof(a)); cout << solution1(i) << " "; } cout << endl << "第三種解法: " << endl; for (int k = 1; k <= 10; ++k) { cout << solution2(k) << " "; } return 0; }