这个算法本身就不多讲了,感觉很暴力。
Luogu P5928
#include<bits/stdc++.h>
#define int long long
using namespace std;
const double eps=1e-3,delta=0.999;
const int N=103;
int n,p;
struct node{int a,b,c,w;bitset<N>v;
}e[104];
struct book{int x,y;
}z[103];
int Ans=1e18;
bitset<N>tmp,vis;
int calc(){int res=0;for(int i=1;i<=p;i++) vis[i]=0;for(int i=1;i<=n;i++){if(tmp[i]) vis|=e[i].v,res+=e[i].w;}for(int i=1;i<=p;i++) if(!vis[i]) return 2e9;return res;
}
void solve(){double T=2333;int ans=calc(),now=ans;while(T>eps){int x=rand()%n+1;tmp[x]=!tmp[x];int k=calc();if(k<ans) ans=k;if(k<now||exp((double)(now-k)/T)>(double)rand()/INT_MAX) now=k;else tmp[x]=!tmp[x];T*=delta; }Ans=min(Ans,ans);
}
int a,b,c,w;
signed main(){srand(time(NULL));cin>>n>>p;for(int i=1;i<=n;i++){cin>>a>>b>>c>>w;e[i]={a,b,c,w,bitset<N>{}};}for(int i=1;i<=p;i++){cin>>z[i].x>>z[i].y;}for(int i=1;i<=n;i++){tmp[i]=1;for(int j=1;j<=p;j++){if(z[j].x*e[i].a+z[j].y*e[i].b<=e[i].c){e[i].v[j]=1;}}}if(calc()==2e9){cout<<"-1";return 0;}double timer=clock();while(clock()-timer<=CLOCKS_PER_SEC*0.98) solve();cout<<Ans;
}
Luogu P1337
#include<bits/stdc++.h>
using namespace std;
double x_ans,y_ans,ans;
int n;
double delta=0.999,Min=1e-14;
struct node{int x,y,w;
}z[3004];
unsigned long long seed=19491001;
double get(double x,double y){double dx=0,dy=0,res=0;for(int i=1;i<=n;i++){dx=x-z[i].x;dy=y-z[i].y;res+=sqrt(dx*dx+dy*dy)*z[i].w;}return res;
}
void solve(){double T=3100;while(T>Min){double x=x_ans+(rand()*2-RAND_MAX)*T;double y=y_ans+(rand()*2-RAND_MAX)*T;double w=get(x,y);if(w<ans){x_ans=x;y_ans=y;ans=w;}else if(exp((double)(ans-w)/T)>(double)rand()/RAND_MAX){x_ans=x;y_ans=y;}T*=delta;}
}
signed main(){ios::sync_with_stdio(false);srand(seed);cin>>n;for(int i=1;i<=n;i++){cin>>z[i].x>>z[i].y>>z[i].w;x_ans+=z[i].w;y_ans+=z[i].y;}x_ans/=n;y_ans/=n;ans=get(x_ans,y_ans);// double timer=clock();solve();solve();solve();solve();// solve();printf("%.3lf %.3lf",x_ans,y_ans);
}
Luogu P2210
#include<bits/stdc++.h>
using namespace std;
int n;
int x,y,w;
int f[103][4];
int pos[1004];
const double T_min=1e-5;
const double delta=0.999;
int GET(){int s=0;for(int i=1;i<=n;i++){for(int j=0;j<3;j++){s+=abs(pos[i]-pos[f[i][j]]);}}return s;
}
int ans;
void solve(){double T=30000;while(T>T_min){x=rand()%n+1;y=rand()%n+1;// while(x==y) y=rand()%n+1;swap(pos[x],pos[y]);int k=GET();if(ans>k){ans=k;}else{if(exp((double)(ans-k)/T)<=(double)rand()/INT_MAX){swap(pos[x],pos[y]);} }T*=delta;}
}
signed main(){cin>>n;for(int i=1;i<=n;i++){for(int j=0;j<3;j++){cin>>f[i][j];}pos[i]=i;}ans=GET();// cout<<ans<<endl;int timer=clock();while(clock()-timer<=CLOCKS_PER_SEC*0.98) solve();cout<<ans/2;
}