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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【算法学习笔记】83.排序辅助 动态规划 SJTU OJ 1282 修路

發(fā)布時間:2025/1/21 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【算法学习笔记】83.排序辅助 动态规划 SJTU OJ 1282 修路 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

此題倒是能用貪心騙點分...

其實對于每一個位置 , 我們知道最后的改善結果一定是原數(shù)列中的數(shù) .?

(因為要盡量減少消耗, 可以考慮減小至和相鄰的相同) 有了這個結論之后, 我們就考慮用dp來做這件事情

首先 存下所有數(shù)據(jù)于 data[]

排序data 得到 data_sort[]

然后用dp[i][j]來表示 前i個元素 以data_sort[j]為結尾 轉(zhuǎn)換成 遞增序列的耗費.

那么我們可以知道

dp[i][j] = min({dp[i-1][k]}) + | data[i]- ?data_sort[j] |

所以直譯為:

for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) for (int k = 1; k <= j ; ++k)tmp = min(tmp,dp[i-1][k]); dp[i][j] = tmp + abs(arr[j]-data[i]);

但是可以有大大的優(yōu)化, 因為第三重循環(huán)式為了計算從dp[i][1]到dp[i][j]的最小值, 我們可以利用一個數(shù)組來dp計算這個最小值.

所以用ass[i][j]來表示從dp[i][1]到dp[i][j]的最小值,

那么對于ass[i][j] 的更新 可有?

ass[i][j] = min(dp[i][j],(j==1 ? INF : (ass[i][j-1])));

當j=1時,ass[i][1] = dp[i][1]

當j>=2時,ass[i][j] = min(dp[i][j],ass[i][j-1]);

所以要先更新dp[i][j]再更新ass[i][j]

因為j的順序是從1到n, data_sort[j]是從小到大的,所以就維護了整體的單調(diào)性 從而得到了答案.

#include <iostream> #include <algorithm> #include <cstring> #include <cmath> using namespace std; typedef unsigned long long ull; const int MaxN = 2000+10; const int INF = 2147483600; int n;int data[MaxN]; int data_sort[MaxN]; int data_sort_d[MaxN]; int dp[MaxN][MaxN]; //dp[i][j] 表示前i個數(shù) 修補為以data_sort[j]為結尾的序列時的消耗最小體力值 int ass[MaxN][MaxN];//用來輔助求最小值的dp過程bool cmp_int_d(const int& a, const int& b){return a>b; }void init(){cin>>n;for (int i = 1; i <= n; ++i){cin>>data[i];data_sort[i] = data[i];}sort(data_sort+1,data_sort+n+1);for (int i = 1; i <= n; ++i){data_sort_d[i] = data_sort[n+1-i];}memset(dp,0,sizeof(dp));memset(ass,0,sizeof(ass)); }int build(int* arr){//cout<<"-----\n";for (int i = 1; i <= n; ++i){for (int j = 1; j <= n; ++j){// for (int k = 1; k <= j ; ++k)// tmp = min(tmp,dp[i-1][k]); dp[i][j] = ass[i-1][j] + abs(arr[j]-data[i]);//cout<<dp[i][j]<<" ";ass[i][j] = min(dp[i][j],(j==1 ? INF : (ass[i][j-1])));//cout<<"("<<ass[i][j]<<") "; }//cout<<endl; }int ans = INF;for (int i = 1; i <= n; ++i)ans = min(ans,dp[n][i]);return ans; }int main(int argc, char const *argv[]) {init();int a = build(data_sort);int d = build(data_sort_d);//cout<<a<<" "<<d<<endl;cout<<min(a,d)<<endl;return 0; }

?

轉(zhuǎn)載于:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1282.html

總結

以上是生活随笔為你收集整理的【算法学习笔记】83.排序辅助 动态规划 SJTU OJ 1282 修路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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