题目大意
给出了一列数,要求通过修改某些值,使得最终这列数变成有序的序列,非增或者非减的,求最小的修改量。
分析
首先我们会发现,最终修改后,或者和前一个数字一样,或者和后一个数字一样,这样才能修改量最小。
我们先根据原数列排序,确定元素的大小关系,对应编号为p[i]
dp[i][j] 表示考虑前i个元素,最后元素为序列中 第j小元素的最优解
dp[i][j] = MIN(dp[i-1][k]) + abs(a[i]-a[p[j]]), (0<k<=j)   
刚开始以为是o(n^3)的复杂度,后来想想,k值在每次j循环的时候就能确定最小值
 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define INF 100000000000000
#define maxn 2005
using namespace std;
int n;
typedef long long LL;
LL a[maxn],b[maxn];
LL dp[maxn][maxn];
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=; i<=n; i++)
{
scanf("%I64d",&a[i]);
b[i]=a[i];
}
sort(b+,b++n);
for(int i=; i<=n; i++)
for(int j=; j<=n; j++)
dp[i][j]=INF;
for(int j=; j<=n; j++)
{
dp[][j]=(a[]-b[j]);
if(dp[][j]<)
dp[][j]=-dp[][j];
} for(int i=; i<=n; i++)
{
LL k=dp[i-][];
for(int j=; j<=n; j++)
{
k=min(dp[i-][j],k);
LL tem=(a[i]-b[j]);
if(tem<)
tem=-tem;
dp[i][j]=min(dp[i][j],k+tem);
// printf("==%I64d\n",dp[i][j]);
}
}
LL minn=INF;
for(int i=; i<=n; i++)
minn=min(minn,dp[n][i]);
printf("%I64d\n",minn);
}
return ;
}

最新文章

  1. 面向对象to1
  2. 开启gpu加速的高性能移动端相框组件!
  3. 让微信扫描直接下载你的APK
  4. BizTalk开发系列(二十三) BizTalk性能指标参考
  5. MFC编程入门之十五(对话框:一般属性页对话框的创建及显示)
  6. stsadm.exe
  7. Delphi 程序结构
  8. ASP.NET中后台注册js脚本攻略(转)
  9. 使用Idea编写javaweb以及maven的综合(一)
  10. eclipse 搭建Robotium环境--apk 环境搭建
  11. 惠普4431s 笔记本配置
  12. MongoDB 监控
  13. C++ bitset用法
  14. 佳佳的Fibonacci
  15. (7)Jquery1.8.3快速入门_内容过滤选择器
  16. 清除DNS缓存(解决能上QQ但是无法上网页问题)
  17. CentOS6.8下安装xz命令
  18. 【托业】【新托业TOEIC新题型真题】学习笔记8-题库五-&gt;P7
  19. webpack 中,loader、plugin 的区别
  20. sql 语句收集

热门文章

  1. VS2003编译后的网站如何修改代码
  2. sql删除语句
  3. js基础之弹性运动(四)
  4. ncs安装及初次运行
  5. 类成员函数作为pthread_create函数参数
  6. 二模 (8) day1
  7. 编码为multipart/form-data自定义类型(包括文件)如何自动绑定到webapi的action的参数里
  8. Java异常--读书笔记
  9. ios开发逆向传值的几种方法整理
  10. 无刷新 checkbox列表的删除