[POJ 3666]Making the Grade[DP]
2016-01-15 19:26
295 查看
题目链接:[POJ 3666]Making the Grade[DP]
题意分析:
含有n个数的序列,允许对序列中的任意一个数加或者减,问:最少更改多少值,使得原序列变成单调递增或者单调递减?
解题思路:
对于一个数字的修改,我们将它修改成序列中有的数是最好的选择(我是靠找不到反例来理解的= =)。那么我们就可以先把这些数字拷贝出来排个序,就有接下来:
设状态dp[i][j]为到第i个数,以b[j]为结尾更改的最少价值。那么有转移方程dp[i][j]=min(dp[i−1][k])+|a[i]−b[j]|(k=0∼j)这个方程是三方的,对于此题显然会T的。注意到min(dp[i-1][k])是前j项的最小值,那么在转移的时候维护这个最小值即可。这样可以降到平方的复杂度。
个人感受:
前n项求和,求最小值等等等,都能这么优化,2333
具体代码如下:
题意分析:
含有n个数的序列,允许对序列中的任意一个数加或者减,问:最少更改多少值,使得原序列变成单调递增或者单调递减?
解题思路:
对于一个数字的修改,我们将它修改成序列中有的数是最好的选择(我是靠找不到反例来理解的= =)。那么我们就可以先把这些数字拷贝出来排个序,就有接下来:
设状态dp[i][j]为到第i个数,以b[j]为结尾更改的最少价值。那么有转移方程dp[i][j]=min(dp[i−1][k])+|a[i]−b[j]|(k=0∼j)这个方程是三方的,对于此题显然会T的。注意到min(dp[i-1][k])是前j项的最小值,那么在转移的时候维护这个最小值即可。这样可以降到平方的复杂度。
个人感受:
前n项求和,求最小值等等等,都能这么优化,2333
具体代码如下:
#include<algorithm> #include<cctype> #include<cmath> #include<cstdio> #include<cstring> #include<iomanip> #include<iostream> #include<map> #include<queue> #include<set> #include<sstream> #include<stack> #include<string> #define ll long long using namespace std; const int INF = 0x7f7f7f7f; const int MAXN = 2e3 + 111; int a[MAXN], b[MAXN]; int dp[MAXN][MAXN]; bool cmp(int a, int b) { return a > b; } int main() { int n; cin >> n; for (int i = 0; i < n; ++i) cin >> a[i], b[i] = a[i]; sort(b, b + n); for (int i = 0; i < n; ++i) dp[0][i] = abs(a[0] - b[i]); int ans1 = INF; for (int i = 1; i < n; ++i) { int pre = dp[i - 1][0]; for (int j = 0; j < n; ++j) { pre = min(pre, dp[i - 1][j]); dp[i][j] = pre + abs(a[i] - b[j]); } } for (int i = 0; i < n; ++i) { ans1 = min(ans1, dp[n - 1][i]); } sort(b, b + n, cmp); for (int i = 0; i < n; ++i) dp[n - 1][i] = abs(a[n - 1] - b[i]); int ans2 = INF; for (int i = n - 2; i >= 0; --i) { int pre = dp[i + 1][n - 1]; for (int j = n - 1; j >= 0; --j) { pre = min(pre, dp[i + 1][j]); dp[i][j] = pre + abs(a[i] - b[j]); } } for (int i = 0; i < n; ++i) { ans2 = min(ans2, dp[0][i]); } cout << min(ans1, ans2) << '\n'; return 0; }
相关文章推荐
- 【中级篇】部署Tomcat+Nginx负载均衡集群
- 学习数据结构之链表
- 分别对三通道赋值img.at<Vec3b>(i,j)[2]=255;
- Raspberry pi 2网络配置
- TOAD连接ORACLE而不装ORACLE 客户端的方法
- 性能测试之----瓶颈分析方法
- 开通博客
- centos7.0 docker安装部署
- OpenSDA
- Java并发编程实战学习笔记(一)-线程安全性
- Web前端/后端
- dpdk-icmpecho
- 初识Android的界面UI
- 高效能程序员的修炼----摘录(一)
- Python中pprint只有在足够长度的内容下才出效果
- php.ini xdebug 配置
- Java提高学习之Object(5)
- POJ2151- Check the difficulty of problems(概率DP)
- uva572 Oil Deposits
- 标准文件IO以及scanf fgets gets 以及printf sprintf fprintf的区别