• Codeforces13C–Sequence(区间DP)


    题目大意

    给定一个含有N个数的序列,要求你对一些数减掉或者加上某个值,使得序列变为非递减的,问你加减的值的总和最少是多少?

    题解

    一个很显然的结果就是,变化后的每一个值肯定是等于原来序列的某个值,因为只需要变为非递减的,所以对于某个数要么不变,要么变成左右附件的某个值。这样我们就可以根据前述条件得出DP方程了:dp[i][j]=min(dp[i][j-1],dp[i-1][j]+|a[i]-b[j]|)(a为原序列,b为排序后的序列),方程的意思是,把序列前i个数变为非递减序列并且以不超过b[j]的值结尾的最小花费,那么它要么是以不超过b[j-1]结尾的最小花费,或者是刚好以b[j]结尾的最小花费

    代码

    第一次提交没用long long呵呵了一次

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    #define MAXN 5005
    #define  INF 0x3f3f3f3f
    typedef long long LL;
    LL dp[MAXN],a[MAXN],b[MAXN];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%I64d",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(j==1)dp[j]+=abs(a[i]-b[j]);
                else
                    dp[j]=min(dp[j-1],dp[j]+abs(a[i]-b[j]));
            }
            printf("%I64d
    ",dp[n]);
            return 0;
    }
  • 相关阅读:
    内存溢出和内存泄漏的区别
    测试管理三要素(人员、过程和技术)
    面试可提问的6个问题
    弱网测试(二)
    js捕获错误
    TortoiseGit自动记住用户名密码的方法
    win7 "com surrogate“ 已停止工作的解决办法
    仿百度图片毛玻璃效果
    毛玻璃效果
    vimium快捷键列表
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3305003.html
Copyright © 2020-2023  润新知