• Making the Grade---poj3666(dp)


    题目链接:http://poj.org/problem?id=3666

    题意:有一个n个数的序列a,现在要把这些序列变成单调增的或者单调减的序列 b ,

    其价值为|AB1| + |AB2| + ... + |AN - BN | 现在要让价值最小;

    b序列表示为 a 的有序序列;

    用dp[i][j]表示把前i - 1个数变成单调且最后一个数是b[j]的最小价值;

    那么dp[i][j] = min(dp[i-1][k]) + abs(a[i]-b[j]);(1<= k <= j);

    看似三层循环,但是求最小值的可以省略;

    k<=j是因为,前i-1个数已经变成单调的了,要想第i个数也是单挑的,那么前i个数就要小于等于b[j];

    题的数据可能比较水,只需求变成单挑递增的即可,否则还要倒着来一遍;

    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define N 2100
    #define PI 4*atan(1.0)
    #define mod 110119
    #define met(a, b) memset(a, b, sizeof(a))
    typedef long long LL;
    
    int a[N], b[N], dp[N][N], n;
    
    int main()
    {
        while(scanf("%d", &n) != EOF)
        {
            for(int i=1; i<=n; i++)
            {
                scanf("%d", &a[i]);
                b[i] = a[i];
            }
            sort(b+1, b+n+1);
    
            met(dp, 0);
    
            for(int i=1; i<=n; i++)
            {
                int Min = INF;
                for(int j=1; j<=n; j++)
                {
                    Min = min(dp[i-1][j], Min);
                    dp[i][j] = Min + abs(a[i]-b[j]);
                }
            }
            int ans = INF;
            for(int i=1; i<=n; i++)
                ans = min(ans, dp[n][i]);
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    添加组合索引时,做相等运算字段应该放在最前面
    常用位运算
    redis php扩展简单使用
    mysql优化之简单概念
    mysql优化之sql语句优化
    简单画图 gd库函数
    win下 安装mongodb
    伪静态之实际应用
    tomcat win简单配置
    docker
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5786825.html
Copyright © 2020-2023  润新知