AtCoder AGC032D Rotation Sort (DP)

Topic Link

https://atcoder.jp/contests/agc032/tasks/agc032_d

answer

Is an immortal title ah ah ah ah. . . atcoder questions really do not come ah QAQ

The first step is immortal transformation: first moved to the other last left this matter can be transformed into the first and the last moved last somewhere between the next (non-integer) and right The same shift.
The question then becomes: there \ (N \) the number of the beginning of each number has a location, you can now spend \ (A \) of the cost of a number of right over any position (not necessarily an integer) , \ (B \) cost to a number left over any position, then find the minimum cost and sorts them!

This is a simple thing DP, provided \ (DP [I] [J] \) ( \ (0 \ Le J \ n-Le \) ) representing the forward \ (I \) number of sorted, the \ ( I \) th interval on \) \) ([j, j + 1 minimum cost in the transfer is easy (note to be considered separately without movement), and the prefix optimization, time complexity \ (O (N ^ 2) \) .

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iostream>
#include<algorithm>
#define llong long long
using namespace std;

inline int read()
{
    int x=0; bool f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
    for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
    if(f) return x;
    return -x;
}

const int N = 5000;
const llong INF = 10000000000000000ll;
int p[N+3],pp[N+3];
llong dp[N+3][N+5],sdp[N+3][N+5];
int n; llong arga,argb;

void update(llong &x,llong y) {x = x<y?x:y;}

int main()
{
    scanf("%d%lld%lld",&n,&arga,&argb);
    for(int i=1; i<=n; i++) {scanf("%d",&p[i]); pp[p[i]] = i;}
    for(int i=0; i<=n; i++) for(int j=0; j<=n; j++) dp[i][j] = sdp[i][j] = INF;
    for(int i=0; i<=n; i++) sdp[0][i] = dp[0][i] = 0ll;
    for(int i=1; i<=n; i++)
    {
        for(int j=0; j<=n; j++)
        {
            if(j==pp[i]) {update(dp[i][j],sdp[i-1][j-1]);}
            llong tmp = sdp[i-1][j]+(j<pp[i]?argb:arga);
            update(dp[i][j],tmp);
//          printf("dp[%d][%d]=%lld\n",i,j,dp[i][j]);
        }
        sdp[i][0] = dp[i][0];
        for(int j=1; j<=n; j++) sdp[i][j] = min(sdp[i][j-1],dp[i][j]);
    }
    llong ans = sdp[n][n];
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/suncongbo/p/11300538.html