题解 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;
} 

猜你喜欢

转载自www.cnblogs.com/sjsjsj-minus-Si/p/11635607.html
今日推荐