蒟蒻写的模拟退火感觉虽然乱七八糟但是希望试一试,求大佬指点
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
int t,n,c[50005],c1[50005],s,s1,ans;
struct lwt
{
int a;
int b;
}game[50005],game1[50005];
bool cmp(lwt a,lwt b)
{
return a.a<b.a;
}
bool cmp1(lwt a,lwt b)
{
return a.b<b.b;
}
void sa();
int get();
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>game[i].a>>game[i].b;
game1[i].a=game[i].a;
game1[i].b=game[i].b;
}
sort(game+1,game+n+1,cmp);
sort(game1+1,game1+n+1,cmp1);
memset(c,0,sizeof(c));
memset(c1,0,sizeof(c1));
s=0;
s1=0;
for(int i=1;i<=n;++i)
{
s+=game[i].a;
c[i]+=max(c[i-1],s)+game[i].b;
}
for(int i=1;i<=n;++i)
{
s1+=game1[i].a;
c1[i]+=max(c1[i-1],s)+game1[i].b;
}
int ans=min(c[n],c1[n]);
int ctrl=275;
while(ctrl--)
sa();
printf("%d\n",ans);
}
return 0;
}
int get()
{
s=0;
s1=0;
memset(c,0,sizeof(c));
memset(c1,0,sizeof(c1));
for(int i=1;i<=n;++i)
{
s+=game[i].a;
c[i]+=max(c[i-1],s)+game[i].b;
}
for(int i=1;i<=n;++i)
{
s1+=game1[i].a;
c1[i]+=max(c1[i-1],s)+game1[i].b;
}
return min(c[n],c1[n]);
}
void sa()
{
double begin1=5000,end1=2e-10,change1=0.7112;
for(double i=begin1;i>end1;i*=change1)
{
int x=rand()%n+1,y=rand()%n+1;
swap(game[x].a,game1[y].a);
swap(game[x].b,game1[y].b);
int sum=get();
if(sum<ans)
ans=sum;
else
{
if(exp((ans-sum)/i)<(double(rand())/RAND_MAX))
swap(game[x].a,game1[y].a);
swap(game[x].b,game1[y].b);
}
}
}