题解 P1284 三角形牧场

DP的做法比较麻烦我并不会

我选择贪心

显然,三边的差越小,他的面积就越大

所以:每次将木板加入当前的最短边即可完成贪心
但是贪心成功的概率较小,这时可以想到使用随机化!!


前置技能

  • 海伦公式:sqrt(p(p-a)(p-b)*(p-c)),其中p=(a+b+c)/2
  • trunc函数来舍尾
#include<bits/stdc++.h>
#define inf 1e9
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++) 
using namespace std;
int n,a[41],ans=-1;

int read()
{
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    return x*f;
}

void wash()//随机洗木板顺序
{
	rep(i,1,n)
	{
		int t=rand()%n;
		a[0]=a[t];
		a[t]=a[i];
		a[i]=a[0];
	}
}

int helen(double a,double b,double c)//海伦公式求面积
{
	if(a+b>c && b+c>a && a+c>b)
	{
		double p=(a+b+c)/2;
		return trunc(sqrt(p*(p-a)*(p-b)*(p-c))*100);
	}
	else return -1;
}

void work()//贪心程序
{
	int p[3],pos;
	p[0]=a[1];
	p[1]=a[2];
	p[2]=a[3];
	rep(i,4,n)
	{
		int min=0x7fffffff;
		rep(j,0,2)
		{
			if(min>p[j])
			{
				min=p[j];
				pos=j;
			}
		}
		p[pos]+=a[i];
	}
	ans=max(ans,helen(p[0],p[1],p[2]));
}

int main()
{
	n=read();
	rep(i,1,n)
		a[i]=read();
	rep(time,1,10000)
	{
		wash();
		work();	
	}
	printf("%d\n",ans);
	return 0;
} 
posted @ 2019-10-08 15:22  设计涉及社稷  阅读(138)  评论(0编辑  收藏  举报