POJ 3666
来源:互联网 发布:java中public的翻译 编辑:程序博客网 时间:2024/06/06 09:32
离散化+dp,好神奇的做法,将一个序列a变成b,并要求每一个元素|a[i] - b[i]|的绝对值尽量小,求最小的绝对值之和。。
如果能想到离散化,这就是一道非常水的题目了。。
因为元素最大为INF,因此不能作为下标,如果将所有值离散化,就可以进行状态转移了。
首先将原来数组排序去重后存到一个t数组里,然后dp[i][j]中的第一维i代表当前到了第几个元素,j表示最后一个数的大小,因为要满足非递减关系,所以只取前一项中最后一个数小于等于当前j的最小值就行。
状态转移:dp[i][j] = abs(t[j] - a[i]) + dp[i - 1][j]。
下面附代码:
#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>using namespace std;const int maxn = 2000 + 10;int a[maxn];int b[maxn];long long dp[maxn][maxn];int n;int nn;const long long INF = 0x7fffffffffffffff;int main(){ while(~scanf("%d", &n)) { for(int i = 0; i < n; ++i) { scanf("%d", &a[i]); b[i] = a[i]; } sort(b, b + n); nn = unique(b, b + n) - b; memset(dp, 0, sizeof(dp)); for(int i = 0; i < nn; ++i) dp[0][i] = abs(a[0] - b[i]); for(int i = 1; i < n; ++i) { long long MIN = dp[i - 1][0]; dp[i][0] = abs(a[i] - b[0]) + MIN; for(int j = 1; j < nn; ++j) { MIN = min(dp[i - 1][j], MIN); dp[i][j] = abs(a[i] - b[j]) + MIN; } } long long MIN = INF; for(int i = 0; i < nn; ++i) { MIN = min(MIN, dp[n - 1][i]); } printf("%I64d\n", MIN); }}
0 0
- poj 3666
- POJ 3666
- poj-3666
- POJ 3666 DP
- poj 3666 线性dp
- POJ 3666 DP
- [DP] POJ 3666
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- [Coursera_Machine_learning]--Model and Cost Funtion
- Python 函数
- C++vector基础容器2.0
- 异常基础
- InputStreamReader和BufferedReader用法及真实案例
- POJ 3666
- c/c++常见知识点
- iOS 事件处理机制与图像渲染过程
- HDU 5813 Elegant Construction (构造有向图)
- JAVA成员变量和局部变量的区别
- POJ-1745 Divisibility
- MFC---多种方式显示位图
- 使用Http访问网络
- 判断素数的几种方法 杭电OJ 1397