AtCoder AGC036D Negative Cycle (图论、DP)

Topic Link

https://atcoder.jp/contests/agc036/tasks/agc036_d

answer

This is how to think out of the ah. . Stunned series. .

The first step is crucial transformation: in the absence of any negative ring means that a map?
There does not exist a negative ring shortest path, we can assign a weight to each point \ (P_i \) (corresponding to the \ (1 \) shortest number to the point, from point \ (1 \) starts numeral ) satisfy any edge \ ((i, j) \ ) have \ (p_j \ GE P_i + W (I, J) \) .
then we let \ (Q_I = P_i-P_ {I +. 1} \) , then Since the right side is \ (1 \) or \ (- 1 \) and there can not be deleted \ (0 \) side, apparently \ (Q \) array values are \ (0 \) or \ (1 \) .
constraint becomes: for each edge \ ((i, j) \ (i> j) \) have \ (\ sum ^ {i- 1} _ {k = i} q_k \ le 1 \) for each edge \ ((i, j) \ (i <j) \) have \ (\ SUM. 1} ^ {J-K = {I} _ q_k \ GE. 1 \) .
the question then is converted into : you give each \ (1 \)To \ ((n-1) \ ) a point \ (Q_I \) assigned a \ (0 \) or \ (1 \) weights, and then delete all the edge does not satisfy the constraints, to minimize the total cost of !
God, this is too god it ......

Then is an easy DP, the set \ (dp [i] [j ] \) represents prior arrangements \ (I \) bit \ (Q \) values, and the force command \ (Q_I =. 1 \) , on one of \ (1 \) position is \ (J \)
then consider enumeration \ (K \) , \ (DP [I] [J] \) was transferred to \ (dp [k] [i ] \) while not legal deleting edges
for \ (a> b \) edge \ ((a, B) \) , to remove all satisfy \ (j <b \ le i <x <a \) edge
for \ (a <b \) edge \ ((a, B) \) , to remove all satisfy \ (j <i <a < b \ le x \) sides
and is easy to use this prefix and a two-dimensional optimization , time complexity \ (O (n-^. 3) \) .

Ah ah ah human wisdom ......

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iostream>
#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 = 500;
llong a[N+3][N+3];
llong s[2][N+3][N+3];
llong dp[N+3][N+3];
int n;

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

llong getsum(int typ,int lx,int rx,int ly,int ry)
{
    return s[typ][rx][ry]-s[typ][lx-1][ry]-s[typ][rx][ly-1]+s[typ][lx-1][ly-1];
}

int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(j==i) continue;
            scanf("%lld",&a[i][j]);
        }
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(i<j) {s[0][i][j] = a[i][j];}
            s[0][i][j] += s[0][i][j-1];
        }
        for(int j=1; j<=n; j++) s[0][i][j] += s[0][i-1][j];
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            if(i>j) {s[1][i][j] = a[i][j];}
            s[1][i][j] += s[1][i][j-1];
        }
        for(int j=1; j<=n; j++) s[1][i][j] += s[1][i-1][j];
    }
    memset(dp,42,sizeof(dp)); 
    dp[0][0] = 0ll;
    for(int i=0; i<=n; i++)
    {
        for(int j=0; j<max(i,1); j++)
        {
            for(int k=i+1; k<=n; k++)
            {
                llong tmp = dp[i][j]+getsum(1,k+1,n,j+1,i)+getsum(0,i+1,k,i+1,k);
                update(dp[k][i],tmp);
            }
        }
    }
    llong ans = dp[n][1];
    for(int i=1; i<=n; i++) update(ans,dp[n][i]);
    printf("%lld\n",ans);
    return 0;
}

Guess you like

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