BZOJ1237: [SCOI2008]配对

来源:互联网 发布:淘宝网上怎样卖东西 编辑:程序博客网 时间:2024/05/16 06:05

将两个数列排序后,因为A,B各不相同,可以发现对于序列A中的Ai,和他匹配的Bj满足abs(i-j)<=2(证明的话想想显然?)
然后可以直接状压,f[i][j]表示匹配完第i个,Bi-1~Bi+2的状态
code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;inline void down(ll &x,const ll y){if(x>y)x=y;}const int maxn = 110000;const int maxd = 16;const ll inf = 1e12;int n,m;int a[maxn],b[maxn];ll f[2][maxd];inline ll Cal(const int x,const int y){return x==y?inf:abs(x-y);}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);    sort(a+1,a+n+1);    sort(b+1,b+n+1);    for(int i=0;i<maxd;i++) f[0][i]=inf;    int now; f[now=0][3]=0;    for(int i=1;i<=n;i++)    {        now=!now; for(int j=0;j<maxd;j++) f[now][j]=inf;        for(int k=0;k<maxd;k++) if(f[!now][k]!=inf)        {            if(!(k&1)) down(f[now][k>>1],f[!now][k]+Cal(a[i],b[i-2]));            else            {                for(int j=-1;j<=2&&i+j<=n;j++) if(!((k>>1)&1<<j+1))                    down(f[now][(k>>1)|(1<<j+1)],f[!now][k]+Cal(a[i],b[i+j]));            }        }    }    ll ans=f[now][3];    if(ans==inf) printf("-1\n");    else printf("%lld\n",ans);    return 0;}
0 0
原创粉丝点击