【算法学习笔记】83.排序辅助 动态规划 SJTU OJ 1282 修路
此題倒是能用貪心騙點分...
其實對于每一個位置 , 我們知道最后的改善結果一定是原數列中的數 .?
(因為要盡量減少消耗, 可以考慮減小至和相鄰的相同) 有了這個結論之后, 我們就考慮用dp來做這件事情
首先 存下所有數據于 data[]
排序data 得到 data_sort[]
然后用dp[i][j]來表示 前i個元素 以data_sort[j]為結尾 轉換成 遞增序列的耗費.
那么我們可以知道
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]);但是可以有大大的優化, 因為第三重循環式為了計算從dp[i][1]到dp[i][j]的最小值, 我們可以利用一個數組來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]是從小到大的,所以就維護了整體的單調性 從而得到了答案.
#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個數 修補為以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; }?
轉載于:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1282.html
總結
以上是生活随笔為你收集整理的【算法学习笔记】83.排序辅助 动态规划 SJTU OJ 1282 修路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android事件传递机制以及onInt
- 下一篇: 【LeetCode】70 - Climb