zoukankan      html  css  js  c++  java
  • P2503 [HAOI2006]均分数据

    Archie

    怎样用模拟退火搞序列

    随机交换就可以了

    dp检查

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int n,m;int a[50],na[50];
    double t;double ans=1e18;
    double delat=0.996;
    double dp[50][50];
    double sum[50];
    double work(){
    	memset(dp,0x7f,sizeof(dp));
    	dp[0][0]=0;
    	sum[1]=na[1];
    	for(int i=2;i<=n;++i)
    	sum[i]=sum[i-1]+na[i];
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=min(m,i);++j){
    			for(int z=0;z<i;++z){
    				dp[i][j]=min(dp[i][j],dp[z][j-1]+((sum[i]-sum[z])-sum[n]/m)*((sum[i]-sum[z])-sum[n]/m));
    			}	
    		} 
    	}
    	return dp[n][m];
    }
    void sa(){
    	double nans=ans;
    	for(int i=1;i<=n;++i){
    		na[i]=a[i];
    	}
    	t=2000;
    	while(t>1e-15){
    		int nx=rand()%n+1;
    		int ny=rand()%n+1;
    		if(nx==ny)
    		 continue;
    		swap(na[nx],na[ny]);
    		double res=work();
    		//cout<<res<<endl;
    		double key=res-nans;
    		if(key<0){
    			nans=res;
    			ans=res;
    			for(int i=1;i<=n;++i){
    				a[i]=na[i];
    			}
    		}else{
    			if(exp(-res/delat)*RAND_MAX<rand())
    			swap(na[nx],na[ny]);
    			else
    			nans=res;
    		}
    		t*=delat;
    	}
    }
    int main(){
    	srand(20040519);
    	srand(rand());
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&a[i]);
    	} 
    	for(int i=1;i<=6;++i){
    		sa();
    		//printf("%.2lf
    ",ans);
    	}
    	printf("%.2lf",sqrt(ans/m));
    	return 0;
    }
    
  • 相关阅读:
    safeNet
    网店
    微信公众号自定义菜单与回车
    西游记对教育的启发
    zencart资源
    cmd批处理常用符号详解
    div垂直居中
    git工作量统计
    VS2012变化的快捷键:
    sql 树 递归
  • 原文地址:https://www.cnblogs.com/For-Miku/p/15028694.html
Copyright © 2011-2022 走看看