动态规划训练23 [Making the Grade POJ
来源:互联网 发布:淘宝网页看不到价格 编辑:程序博客网 时间:2024/05/23 19:14
Making the Grade
POJ - 3666这道题目有点意思。
我们定义dp[i][j]表示的含义是把包含前i个元素的子序列变成非递减的子序列,并且最后一个元素变成j所需要耗费的最小代价
那么状态转移方程可以写出来就是:
dp[i][j] = min(dp[i-1][k] + abs(num[i] - j)) 其中 0<= k <= j
这个方程很简单对吧,但是问题来了
这样的话,空间复杂度显然会超,而且时间复杂度也会超
那么我们来考虑一下优化问题
首先进行空间优化,由于最多只有2000个元素,所以说不同高度的值最多也只能有2000个,那么我们对高度做个离散化,就很容易解决MLE的问题了。
下面的问题回到了时间上,由于时间是O(n3)的,而要在限定时间内完成,我们可以把时间优化到O(n2)
注意到我们在状态转移方程里,花了O(n)的时间去求了k不超过j时候的dp[i-1][k]的最小值。其实我们可以开一个数组MN[i][j]里面恰好就存不超过j时候的dp[i-1][k]的最小值。
在动态规划的过程中进行维护这个数组就OK了
#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <vector>using namespace std;const int MAX = 2005;const int INF = 1e9;int a[MAX];int ss[MAX];int dp[MAX][MAX];int MN[MAX][MAX];int main(){int N;scanf("%d",&N);for(int i = 0;i < N;i++){scanf("%d",&a[i]);ss[i] = a[i];}sort(ss,ss+N);int un = unique(ss,ss+N) - ss;for(int i = 0;i < N;i++){a[i] = lower_bound(ss,ss+un,a[i]) - ss;}for(int i = 0;i < un;i++){dp[0][i] = abs(ss[i] - ss[a[0]]);MN[0][i] = min((i == 0? 0 :MN[0][i-1]),dp[0][i]);}for(int i = 1;i < N;i++){dp[i][0] = dp[i-1][0] + abs(ss[0] - ss[a[i]]);MN[i][0] = dp[i][0];for(int j = 1;j < un;j++){dp[i][j] = INF;//for(int k = 0;k <= j;k++)//dp[i][j] = min(dp[i][j],dp[i-1][k] + abs(ss[a[i]] - ss[j]));dp[i][j] = min(dp[i][j],MN[i-1][j] + abs(ss[a[i]] - ss[j]));MN[i][j] = min(MN[i][j-1],dp[i][j]);}}int ans = INF;for(int i = 0;i < un;i++){ans = min(ans,dp[N-1][i]);}cout<<ans<<endl;return 0;}
阅读全文
0 0
- 动态规划训练23 [Making the Grade POJ
- poj 3666 Making the Grade (动态规划)
- 动态规划-POJ 3666 Making the Grade
- 动态规划 Making the Grade
- poj 3666 Making the Grade (动态规划)
- POJ 3666 Making the Grade(动态规划)
- poj 3666 Making the Grade 动态规划+滚动数组
- poj 3666 Making the Grade (动态规划)
- poj 3666 Making the Grade (离散化+动态规划)
- POJ3666——Making the Grade(动态规划)
- 动态规划——POJ3666 Making the Grade
- POJ3666 Making the Grade题解-动态规划dp
- POJ 3666 Making the Grade
- POJ 3666 Making the Grade
- POJ 3666 Making the Grade
- poj 3666--Making the Grade
- poj 1527 Making the Grade
- POJ 3666 Making the Grade
- 走着走着...
- String、StringBuffer、StringBudder区别
- 动态规划——最大递增子序列
- 【0052】mysql索引类型及索引方法
- 第一章 开始 学习笔记
- 动态规划训练23 [Making the Grade POJ
- Codeforces 455D Serega and Fun【解法二】
- 最大熵模型与EM算法
- 30天自制操作系统(第02天)–汇编语言学习和MakeFile入门
- HDU 4694 Important Sisters【支配树】
- 集训记录第四天关于文件
- MNIST数字识别问题
- css位置尺寸宽高(width,clientWidth,offsetWidth)
- Kingdoms UVA