码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3666(Making the Grade)

时间:2020-04-12 16:25:09      阅读:58      评论:0      收藏:0      [点我收藏+]

标签:std   朴素   class   理解   取值   规划   ems   bsp   突破口   

题目链接:http://poj.org/problem?id=3666

 

题意:农夫约翰想修一条尽量平缓的路,路的每一段海拔是A_i,修理后是B_i,花费|A_i – B_i|,求最小花费。平缓的意思是海拔单调增或单调减(非严格)

 

思路:

这是一道动态规划的问题,突破口是:每个数最后必然是原序列中的数。

用dp[i][j]表示:前i个数构成的序列,这个序列最大值为j,dp[i][j]的值代表相应的cost。

状态转移方程:dp[i][j]=abs(j-w[i])+min(dp[i-1][k])    (k<=j)

网上很多都是说用离散化的思想,但是一直不是很理解这是什么意思,就是将序列排序一下,然后用位置的前后关系来制定其值,这样时间复杂度变成O(N^2).

不是很理解别人的思路,我就想的朴素一点,大概就是把for 循坏 j 的数值的取值范围缩小一些

 

ac代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define MAX_N 2005
using namespace std;
typedef long long ll;

ll a[MAX_N],b[MAX_N];
ll dp[MAX_N][MAX_N];
int n;

int main(void){	
	while(~scanf("%d",&n)){
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++){
			scanf("%lld",&a[i]);
			b[i]=a[i];
		}
		sort(b+1,b+n+1);
		
		for(int i=1;i<=n;i++){
			ll mn=dp[i-1][1];
			for(int j=1;j<=n;j++){
				mn=min(mn,dp[i-1][j]);
				dp[i][j]=abs(a[i]-b[j])+mn;
			}
		}
		ll ans=dp[n][1];
		for(int i=2;i<=n;i++)
			ans=min(ans,dp[n][i]);
		printf("%lld\n",ans);	
	}

	return 0;
}

  

 

POJ 3666(Making the Grade)

标签:std   朴素   class   理解   取值   规划   ems   bsp   突破口   

原文地址:https://www.cnblogs.com/jaszzz/p/12685454.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!