zoukankan      html  css  js  c++  java
  • POJ 3666 Making the Grade

    POJ_3666

        由于递增和递减是类似的,下面不妨只讨论变成递增序列的情况。

        我们可以用f[i][j]表示递推到第i个数时,将第i个数变成<=j且满足序列是非减的所需要的最小的代价。由于j的范围较大,可以先离散化,不妨设最后一共有S个不同的数,那么我们要计算的就是f[N][S]。

        可以得到f[i][j]=std::min(f[i-1][j]+abs(...),f[i][j-1]),式子中的...表示省略了一部分内容。如果还想优化空间的话,用滚动数组实现即可。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXD 5010
    typedef long long LL;
    int N, S, a[MAXD], rank[MAXD];
    LL f[MAXD];
    struct Di
    {
        int id, v;
        bool operator < (const Di &t) const
        {
            return v < t.v;
        }
    }di[MAXD];
    LL deal()
    {
        int i, j;
        for(i = 1; i <= N; i ++) di[i].id = i, di[i].v = a[i];
        std::sort(di + 1, di + 1 + N);
        rank[di[1].id] = S = 1;
        for(i = 2; i <= N; i ++)
        {
            if(di[i].v != di[i - 1].v) di[++ S].v = di[i].v;
            rank[di[i].id] = S;
        }
        memset(f, 0, sizeof(f));
        for(i = 1; i <= N; i ++)
        {
            f[0] = 0x3f3f3f3f3f3f3f3fll;
            for(j = 1; j <= S; j ++)
                f[j] = std::min(f[j - 1], f[j] + std::abs(a[i] - di[j].v));
        }
        return f[S];
    }
    void solve()
    {
        int i;
        LL ans = deal();
        for(i = 1; i <= N / 2; i ++) std::swap(a[i], a[N - i + 1]);
        ans = std::min(ans, deal());
        printf("%lld\n", ans);
    }
    int main()
    {
        while(scanf("%d", &N) == 1)
        {
            for(int i = 1; i <= N; i ++) scanf("%d", &a[i]);
            solve();
        }
        return 0;
    }

     

  • 相关阅读:
    HTTP协议 学习笔记一
    web发展历史
    Easydarwin加FFMPEG实现HLS流视频点播
    C# Socket异步实现消息发送--附带源码
    C# Activex调用USB摄像头--附带源码
    C# listbox DataSource数据绑定--一年半以前的bug
    ASP.NET MVC WebAPI实现文件批量上传
    ASP.NET MVC使用SignalR统计在线用户人数
    Chart.js Y轴数据以百分比展示
    Java获取字符串信息
  • 原文地址:https://www.cnblogs.com/staginner/p/2706987.html
Copyright © 2011-2022 走看看