bzoj 4670 佛罗里达 Posted on 2019-05-24 | Edited on 2019-05-26 | Views: 随机乱搞. 随机做很多次,每次 $random\ shuffle$ 出一个加点的序列,然后按照这个序列加点. 每次贪心判,加在哪个集合里面能使答案增加的量更小,就加在哪个里面. 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182#include<bits/stdc++.h>using namespace std;typedef long long ll;inline int read(){ int out=0,fh=1; char jp=getchar(); while ((jp>'9'||jp<'0')&&jp!='-') jp=getchar(); if (jp=='-') fh=-1,jp=getchar(); while (jp>='0'&&jp<='9') out=out*10+jp-'0',jp=getchar(); return out*fh;}const int T=800;const int inf=0x7fffffff;const int MAXN=256;int n,val[MAXN][MAXN],p[MAXN];int A[MAXN],sizA,B[MAXN],sizB,mxA,mxB;ll ans;int main(){ srand(time(NULL)); while(~scanf("%d",&n)) { ans=inf; memset(val,0,sizeof val); for(int i=1;i<n;++i) for(int j=i+1;j<=n;++j) val[i][j]=val[j][i]=read(); for(int i=1;i<=n;++i) p[i]=i; for(int t=1;t<=T;++t) { ll res=0; random_shuffle(p+1,p+1+n); sizA=sizB=0; mxA=mxB=0; for(int i=1;i<=n;++i) { int valA=0,valB=0; for(int j=1;j<=sizA;++j) valA=max(valA,val[p[i]][A[j]]); for(int j=1;j<=sizB;++j) valB=max(valB,val[p[i]][B[j]]); if(valA<=mxA && valB<=mxB) { int k=rand()&1; if(k) A[++sizA]=p[i]; else B[++sizB]=p[i]; continue; } if(valA-mxA<=valB-mxB) { if(valA-mxA>0) { res+=valA-mxA; mxA=valA; } A[++sizA]=p[i]; } else { if(valB-mxB>0) { res+=valB-mxB; mxB=valB; } B[++sizB]=p[i]; } if(res>=ans) break; } ans=min(ans,res); } cout<<ans<<endl; } return 0;}