题意:给定n(n<=9)个碗,然后每个有r1,r2,h(r1<r2)三个属性,问所有的碗叠放在一起,的最小高度多少?如图叠放
图片说明
题解:n<=9???阶乘枚举9!=362880,稳过..........
然后每次从下往上放,好计算,如果从上往下,像图右这种...........
然后对于每次放的情况,我们假设上面的杯子为1号杯子,下面为2号杯子

第一种情况:1号杯子可以直接放到2号杯子底部(灵魂画师....凑后看,大概这意思)

图片说明
红蓝代表两种极端情况

第二种情况:右图1号位置和3号位置情况

第三种情况:左图的情况

需要计算在那些位置会卡住

第四种情况:右图2号位置和3号位置情况

然后对于每种情况更新新的碗

#include<bits/stdc++.h>
using namespace std;
struct data
{
    double a,b,c,d;
}a[21],b[21];
int n,c[21];
double x,y,z;
data putin(double a,double b,double c,double d)
{
    data aa;
    aa.a=a;
    aa.b=b;
    aa.c=c;
    aa.d=d;
    return aa;
}
double getxl(data a)
{
    return (a.d-a.b)/(a.c-a.a);
}
double work(data a,data b)//两个碗放置的高度 
{
    double p=a.b;
    if(b.a>=a.c)
    {
        return a.d;
    }
    a.b=0;
    a.d-=p;
    if(getxl(a)>getxl(b))
    {
        if(b.c>=a.c)
        {
            double k=a.d-(a.c-b.a)*getxl(b);
            return p+max(k,0.0);
        }
        double k=a.d-b.d-(a.c-b.c)*getxl(a);
        return p+max(k,0.0);
    }else{
        if(a.a>b.a)
        {
            return p;
        }
        double k=a.d-(a.c-b.a)*getxl(a);
        return p+max(k,0.0);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf%lf",&x,&y,&z);
        a[i]=putin(y,0.0,z,x);
    }
    for(int i=1;i<=n;i++)
    {
        c[i]=i;
    }
    double minn=1e9;
    while(1)//计算每种排列的总高度 
    {
        b[0]=putin(1e9,0.0,1e9,0.0);
        for(int i=1;i<=n;i++)
        {
            double maxn=0;
            for(int j=0;j<i;j++)
            {
                maxn=max(maxn,work(b[j],a[c[i]]));
            }
            b[i]=putin(a[c[i]].a,a[c[i]].b+maxn,a[c[i]].c,a[c[i]].d+maxn);//放好的碗 
        }
        double maxn=0;
        for(int i=1;i<=n;i++)
        {
            maxn=max(maxn,b[i].d);
        }
        minn=min(minn,maxn);
        if(!next_permutation(c+1,c+n+1))//下一种排列 
        {
            break;
        } 
    }
    printf("%.0lf\n",minn);
    return 0;
}