Codeforces 1215E. Marbles

Portal

Notice that the value of $ a $ amount is not large, considering the pressure like $ dp $

Provided $ f [S] $ denotes the number determined at this time is set $ S $, and a minimum number of exchanges in a certain order from the beginning of the complete series arrangement

Then the number of each state enumeration last fill, plus the cost of taking the minimum can be

The biggest problem now is how to count the cost ... ???

We noticed two numbers adjacent to each exchange, both the number and relative position of the other numbers are the same (I think this is the crux of the whole problem)

When that is in the best case, we exchanged numbers $ x $ unification to a segment, the number is the number of the cost generated by this number before each original position and this position has not determined at this time ....

Put it well around, ah, look at the code to understand it better ............

The complexity of the count reached $ 1e8 $ level, but $ CF $ run fast, this question time and long, so it is stable

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar ();}
     the while (CH> = ' 0 ' && CH <= ' . 9 ' ) = {X (X << . 1 ) + (X << . 3 ) + (CH ^ 48 ); CH = getchar ();}
     return X * F; 
} 
const  int N = 4E5 + . 7 , M = ( . 1 << 20 is ) + . 7 ;
 int n-, A [N], B [N], CNT [ 27 ]; 
LL CST [ 27 ] [ 27 ] , F [M];
 // CST [i] [J] represents the value i to the cost of prior universal switching value J 
int main () 
{ 
    n-=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=20;j++)
            cst[a[i]][j]+=cnt[j];
        cnt[a[i]]++;
    }
    int mx=(1<<20)-1;
    memset(f,0x3f,sizeof(f)); f[0]=0;
    for(int i=1;i<=mx;i++)
        for(int j=0;j<20;j++)
        {
            if(!((i>>j)&1)) continue;
            ll t=0;
            for(int k=0;k<20;k++)
            {
                if((i>>k)&1) continue;
                t+=cst[j+1][k+1]; // costs and the cost of the exchange and the number of all at this time not determined 
            } 
            F [I] = min (F [I], F [I ^ ( . 1 << J)] + T); 
        } 
    the printf ( " % LLD \ n- " , F [MX]);
     return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/LLTYYC/p/11532671.html