zoukankan      html  css  js  c++  java
  • codeforces 713C C. Sonya and Problem Wihtout a Legend(dp)

    题目链接:

    C. Sonya and Problem Wihtout a Legend

    time limit per test
    5 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Sonya was unable to think of a story for this problem, so here comes the formal description.

    You are given the array containing n positive integers. At one turn you can pick any element and increase or decrease it by 1. The goal is the make the array strictly increasing by making the minimum possible number of operations. You are allowed to change elements in any way, they can become negative or equal to 0.

    Input

    The first line of the input contains a single integer n (1 ≤ n ≤ 3000) — the length of the array.

    Next line contains n integer ai (1 ≤ ai ≤ 109).

    Output

    Print the minimum number of operation required to make the array strictly increasing.

    Examples
    input
    7
    2 1 5 11 5 9 11
    output
    9
    input
    5
    5 4 3 2 1
    output
    12

    题意:

    把这个序列变成严格的单调递增序列,每+1或者-1都花费1,最小花费是多少;

    思路:

    严格单调递增的变成非严格的可以a[i]-i;然后就是转移了;
    dp[i][j]表示第i个数变成j可以满足题目要求的最小花费,现在dp[i][j]=min(dp[i-1][k])+abs(a[i]-j);
    j的范围太大,可以排序离散化,用j表示第j个数,那么dp[i][j]=min(dp[i-1][k])+abs(a[i]-b[j]);
    这样转移的时间复杂度是O(n*n*n)的,所以还要优化,还可以发现dp[i][j]的转移方程中min(d[i-1][k])是上一层的前缀最小值;
    所以可以用一个数组保存下来,复杂度就降为O(n*n)了;

    AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <bits/stdc++.h>
    #include <stack>
    #include <map>
      
    using namespace std;
      
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
      
    typedef  long long LL;
      
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
      
    const int mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e18;
    const int N=(1<<20)+10;
    const int maxn=3e3+110;
    const double eps=1e-12;
     
    
    int n,a[maxn],b[maxn];
    LL dp[maxn][maxn],f[maxn];
    int main()
    {
        read(n);
        For(i,1,n)
        {
            read(a[i]);
            a[i]=a[i]-i;
            b[i]=a[i];
        }
        sort(b+1,b+n+1);
        For(i,0,n)f[i]=inf;
        For(i,1,n)
        {
            For(j,1,n)
            {
                if(i==1)dp[i][j]=abs(a[i]-b[j]);
                else dp[i][j]=f[j]+abs(a[i]-b[j]);
                f[j]=min(f[j-1],dp[i][j]);
            }
        }
        cout<<f[n]<<endl;  
        return 0;
    }
    
    
    

      

     

      



  • 相关阅读:
    0603 学术诚信与道德
    0601 新的冲刺
    0525 Scrum 项目7.0
    0523 Scrum 项目6.0
    0518 Scrum项目5.0
    0512 Scrum 4.0
    0512 操作系统之进程调度
    0511 backlog
    0506 Scrum 项目1.0
    复利计算再升级
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5876208.html
Copyright © 2011-2022 走看看