日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UVA - 10003 - Cutting Sticks

發(fā)布時間:2023/12/15 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UVA - 10003 - Cutting Sticks 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原命題鏈接:PDF/Vjudge


題目的意思是:告訴木棍的總長度,切點個數(shù),和切點位置。每次切割花費的力氣為切割的木棍的長度,求出最小花費的力氣值。

還沒怎么開始看dp,一開始看這道題目,想起了做過的一道拼接木塊的題目,是用貪心AC的,本以為倒著寫過去就完事,但是測試數(shù)據(jù)的時候發(fā)現(xiàn),我去,差距太大了哦。后來一陣計算反思:貪心做不對,要動態(tài)規(guī)劃。(貪心只能過樣例)

沒專業(yè)加仔細學習過動態(tài)規(guī)劃的我,連蒙加猜加上數(shù)據(jù)找錯,最后上交終于半夜AC,剛想一陣狼嚎馬上閉住嘴了。


先放上代碼興奮一下:

#include <bits/stdc++.h> using namespace std; int a[500], dp[100][100]; int dps(int left, int right) { if (dp[left][right] >= 0) return dp[left][right]; if (right - left == 1) return 0; int minx = 0xFFFFFFF; for (int k = left + 1; k < right; k++) { minx = min(minx, dps(left,k) + dps(k,right) + a[right] - a[left]); //cout << a[left] << " " << a[k] << " " << a[right] << " " << minx << endl;//測試的時候用的 } return dp[left][right]= minx; } int main() { int length; while (cin >> length && length) { memset(a, 0, sizeof(a)); memset(dp, -1, sizeof(dp)); int cnt; cin >> cnt; for (int i = 1; i <= cnt; i++) cin >> a[i]; a[cnt + 1] = length; int ans = dps(0, cnt+1); cout << "The minimum cutting is "; cout << ans << "." << endl; /*for (int i = 0; i < 5; i++)//測試的時候用的 { for (int j = 0; j < 5; j++) cout << " " << dp[i][j]; cout << endl; }*/ } system("pause"); return 0; }

思路重現(xiàn):(大佬勿噴)一段木頭,已知切點(我們可以把兩頭的位置也看作切點),我們要切割的話,如果只有一個切割點的話,是好求解的,我們可以用右端點減去左端點就得到花費的力氣值,但是如果有多段呢?這里想到可以用二維數(shù)組的下標來的表示左切點和右切點來記錄切割某一段區(qū)間的力氣值。那么如果有多個切點呢,我們可以通過遞歸來找到某一段間隔區(qū)間的切割的力氣值,如果沒有儲存當前區(qū)間,說明他要么是中間沒有多余切點的切點(直接右端點減去左端點),要么是還沒有計算(繼續(xù)遞歸),這樣的話,就可以得到每兩個區(qū)間上的切割的最小力氣值。最終的數(shù)值都是基于每一個區(qū)間上的最小的力氣值,這樣最后也是最小的力氣值。采用遞歸的方式,一開始相當于最先著眼于每兩個相鄰的切點(最后一層遞歸終止),然后逐步擴大視野(到達上層遞歸),求出整個區(qū)間的力氣值。

搬出一組(改了很久的)數(shù)據(jù)給自己以后看:

10 3 1 5 9 5 9 10 5 1 5 10 14 1 5 9 8 1 9 10 14 0 1 10 24 0 1 5 5 0 5 10 20 0 1 9 17 0 5 9 14 0 9 10 20 The minimum cutting is 20. -1 -1 5 14 20 -1 -1 -1 8 14 -1 -1 -1 -1 5 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

下面是最后打出來的表(可能是這么叫。。。)

通過上面的思路應該可以看得出來

上方的輸出就是切割某兩個存在中間切點的切點的時候花費的最小力氣值:

5 9 10 5 就是說, 從5-10在9處切點切割開來,花費的最小力氣值是5. 1 5 10 14就是說, 從1-10在5切割開來花費的最小力氣值是14,

怎么來的呢:1-10上有兩個切點,要在5切開,這個時候的力氣值肯定會有10-1=9,就是切割5花費的力氣,

然后還需要5-10的力氣值,上一行已經(jīng)算出來了

就是5,加起來就是14.以此類推··· ···


最后

1.在寫的時候一開始不是很嚴謹,定義minx的時候沒有定義很大,導致出錯,后來定義了一個大數(shù)就好了。

2.還有就是一開始沒保存結(jié)果,就是沒有dp那個數(shù)組,一直超時,后來才加上用數(shù)組下標來表示切點,減少遞歸次數(shù)。

總結(jié)

以上是生活随笔為你收集整理的UVA - 10003 - Cutting Sticks的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。