POJ3666(Making the Grade)

链接:https://vjudge.net/problem/POJ-3666
思路:(本题其实可以只用求递增,数据出的有失误)一直在思考怎么表示状态,猜到了最后结果肯定都是原来的几个数,所以我们可以考虑离散化,考虑到后一位是否要变取决于前一位的最大值,那么我们用dp[i][j]表示枚举到第i个数,且最后一位为第j大的数,转移的话dp[i][j] = min(dp[i-1][1,2,3,....j-1]) +abs(a[i]-c[j]),其实不需要枚举k,用一个变量在递推的时候维护最小值就可以了,好好思考一下离散化+dp的操作。
代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2010;
ll a[maxn];
ll c[maxn];
int n;
ll dp[maxn][maxn];

int main(){
    while(~scanf("%d",&n)){
        memset(c,0,sizeof(c));
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]),c[i] = a[i];
        memset(dp,0,sizeof(dp));
        sort(c+1,c+n+1);
        int len  = unique(c+1,c+n+1)-c-1;
        for(int i=1;i<=n;i++){
    //递推时维护最小值        
    long long minv = dp[i-1][1];
            for(int j=1;j<=len;j++){
                minv = min(minv,dp[i-1][j]);
                dp[i][j] = minv+abs(a[i]-c[j]);
            }
        }
        ll res = 1e18;
        for(int i=1;i<=len;i++)res = min(res,dp[n][i]);
        printf("%lld\n",res);
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,771评论 0 33
  • 1. 关于诊断X线机准直器的作用,错误的是()。 (6.0 分) A. 显示照射野 B. 显示中心线 C. 屏蔽多...
    我们村我最帅阅读 10,832评论 0 5
  • 简介 搜索迷宫(BFS+队列) 最短路Dijkstra+邻接矩阵Dijkstra+链式前向星+优先队列Bellma...
    染微言阅读 431评论 0 1
  • 1.选择镜像 点击从镜像市场选择就可进入 本人选择的是: LAMP环境(CentOS7.2 | Apache PH...
    笃Boy阅读 905评论 0 0
  • 人真心是个偷懒的动物,节前各种计划,在节日玩的时候统统忘记,重新调整时状态要很多时间,特别是写作这样不擅长的事情...
    春天雨1阅读 151评论 0 0