随机化乱搞调整
先暴力枚举3的情况,然后贪心出一组1,2的顺序
随机调整顺序,模拟看是否更优,更优则变更为该顺序
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> using namespace std; const int inf=1e9; const int N=20+5; int s1[N],tp1,s2[N],tp2; int a[N],b[N],t[N],n,ans; bool ch[N]; bool cmp1(int i,int j){ if(b[i]==b[j])return a[i]<a[j]; return b[i]>b[j]; } bool cmp2(int i,int j){ if(a[i]==a[j])return b[i]<b[j]; return a[i]>a[j]; } int calc(){ int suma=0,sumb=0; for(int i=1;i<=tp2;i++)sumb+=b[s2[i]]; for(int i=1;i<=tp1;i++){ suma+=a[s1[i]]; if(suma<=sumb)sumb+=b[s1[i]]; else sumb=suma+b[s1[i]]; } int sum=sumb; suma=sumb=0; for(int i=1;i<=tp1;i++)suma+=a[s1[i]]; for(int i=1;i<=tp2;i++){ sumb+=b[s2[i]]; if(sumb<=suma)suma+=a[s2[i]]; else suma=sumb+a[s2[i]]; } sum=max(sum,suma); return sum; } void work(){ tp1=tp2=0; for(int i=1;i<=n;i++)if(ch[i])s2[++tp2]=i;else s1[++tp1]=i; sort(s1+1,s1+1+tp1,cmp1); sort(s2+1,s2+1+tp2,cmp2); int sum=calc(); for(int i=1;i<=2000;i++){ int a1,a2,b1,b2; if(tp1){ a1=rand()%tp1+1,a2=rand()%tp1+1; swap(s1[a1],s1[a2]); } if(tp2){ b1=rand()%tp2+1,b2=rand()%tp2+1; swap(s2[b1],s2[b2]); } int tmp=calc(); if(tmp>=sum){ if(tp1)swap(s1[a1],s1[a2]); if(tp2)swap(s2[b1],s2[b2]); }else sum=tmp; } ans=min(ans,sum); } void dfs(int i){ if(i>n)work(); else{ if(t[i]==1)ch[i]=0,dfs(i+1); else if(t[i]==2)ch[i]=1,dfs(i+1); else{ ch[i]=0;dfs(i+1); ch[i]=1;dfs(i+1); } } } int main(){ //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); srand(541213); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d",&t[i],&a[i],&b[i]); ans=inf; dfs(1); printf("%d\n",ans); return 0; }