站外题退火求助
  • 板块学术版
  • 楼主KυρωVixen
  • 当前回复12
  • 已保存回复12
  • 发布时间2022/12/31 10:21
  • 上次更新2023/10/24 06:03:40
查看原帖
站外题退火求助
765382
KυρωVixen楼主2022/12/31 10:21

土豆先生开了两家新店卖土豆。他买了NN袋土豆,其中第ii 袋价值为 aia_i,袋里有cic_i个土豆。他打算把这NN袋土豆整袋整袋地分在两个店里。

在每家店中,土豆的平均价格等于这家店里所有袋的土豆的总价比上土豆的个数。(注意是个数而不是袋数!)

P1P_1为第一家店的土豆平均价格,P2P_2为第二家店的土豆平均价格。土豆先生希望在至少有一家店里土豆袋数正好等于LL袋的情况下,最小化P1×P2P_1 \times P_2 的值。

这题明摆着退火(N100N\leq100)我什么我的程序爆零?求

#include<bits/stdc++.h>
using namespace std;
const double start=1e5;
const double eps=1e-7;
const double drop=0.99;
int n,l1,l2;
double ans=1919810.0;
struct pot{
	int val,gs;
}m1[101],m2[101];
double cnt(){
	int gs1=0,gs2=0,val1=0,val2=0;
	for(int i=0;i<l1;i++) val1+=m1[i].val,gs1+=m1[i].gs;
	for(int i=0;i<l2;i++) val2+=m2[i].val,gs2+=m2[i].gs;
	return (1.0*val1/gs1)*(1.0*val2/gs2);
}
void SA(){
	double ntemp=start,cale;
	for(;ntemp>eps;ntemp*=drop){
		int i1=rand()%l1,i2=rand()%l2;
		swap(m1[i1],m2[i2]);
		cale=cnt();
		if(cale<ans){
			ans=cale;
			continue;
		}
		else{
			if(exp((cale-ans)*start/ntemp)<rand()/32768.0){
				swap(m1[i1],m2[i2]);
			}
		}
	}
}
int main(){
	srand(time(0));
	cin>>n>>l1; l2=n-l1;
	for(int i=0;i<l1;i++) cin>>m1[i].gs;
	for(int i=0;i<l2;i++) cin>>m2[i].gs;
	for(int i=0;i<l1;i++) cin>>m1[i].val;
	for(int i=0;i<l2;i++) cin>>m2[i].val;
	for(int i=0;i<l1*l2*n;i++){
		SA();
	}
	cout<<fixed<<setprecision(3)<<ans<<endl;
	for(int i=0;i<l1;i++){
		cout<<m1[i].gs<<" "<<m1[i].val<<endl;
	} 
	cout<<endl;
	for(int i=0;i<l2;i++){
		cout<<m2[i].gs<<" "<<m2[i].val<<endl;
	}
}
2022/12/31 10:21
加载中...