洛谷 P2503 [HAOI2006]均分資料 隨機化貪心

折翼的小鳥先生發表於2020-10-23

洛谷P2503 [HAOI2006]均分資料(隨機化貪心)

現在來看這個題就是水題,但模擬賽時想了1個小時貪心,推了一堆結論,最後發現貪心做

不了,

又想了半個小時dp 發現dp好像也做不了,在隨機化貪心和模擬退火

選了模擬退火但寫炸了。(我怎麼這麼水)。我們來看這個題,採取

隨機化貪心,利用random_shuffle函式將所有數字不停隨機

化,每次

隨機化後貪心的取就可以,因為採取的是隨機化貪心,所以貪心策略不必最優,我們用x陣列去存

儲每個位置的值,列舉每一個數字,將數字加到最小的位置即可,我們已知最小位置的值一定小

於品均數,所以加到最小位置是較優的。
放程式碼吧

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
const int maxn=1e4;
int n,m;
int a[maxn];
int x[maxn];
double xl,ans=0x3f3f3f3f;
void slove(){
	memset(x,0,sizeof(x));
	for(int i=1;i<=n;i++){
		int p=1;
		for(int j=1;j<=m;j++){
			if(x[j]<x[p])
				p=j;
		}
		x[p]+=a[i];
	}
	double cnt=0;
	for(int i=1;i<=m;i++){
		cnt+=pow(xl-x[i],2);
	}
	cnt=cnt/(double)m;
	ans=min(ans,cnt);	
}
int main(){
//	freopen("a.in","r",stdin);
	scanf("%d%d",&n,&m);
	double add=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		add+=a[i];
	}
	xl=add/m;
//	cout<<xl<<endl;
	int t=100000;
	while(t--){
		random_shuffle(a+1,a+1+n);
		slove();
	}
	ans=sqrt(ans);
	printf("%.2f",ans);
	return 0;
}
```P2503 [HAOI2006]均分資料 隨機化貪心

相關文章