BZOJ3850: ZCC Loves Codefires

考虑最优的顺序满足什么性质
BZOJ3850: ZCC Loves Codefires_第1张图片
设两个部件A,B顺序为A在B前面,费用分别是a,b,耗时ta,tb,中间部分费用和S,耗时和T
如果最优顺序中A在B前面(A,B前后的部件显然不需要考虑),则有
ata+Sta+b(ta+T+tb)<btb+Stb+a(tb+T+ta)
Sta+bta+bT<Stb+atb+aT
这么看很难看出什么性质,我们考虑中间没有部件,A,B相邻的时候,S=T=0
bta<atb 也即 btb<ata
得出结论按 xtx 从大到小排

等下….这个结论是我们在相邻这个特殊情况得到的,中间有数时会不会不成立?

因为此时我们已经按照 xtx 排序,可以得到 ata>ST>btb
于是 Sta<aT , bT<Stb , bta<atb ,三个不等式加起来就是上面那个柿子qaq

code:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;

inline void read(int &x)
{
    char c; while(!((c=getchar())>='0'&&c<='9'));
    x=c-'0';
    while((c=getchar())>='0'&&c<='9') (x*=10)+=c-'0';
}
const int maxn = 110000;

int n;
struct node
{
    int x,y;
    friend inline bool operator <(const node a,const node b)
    {
        return a.x*b.y-b.x*a.y>0;
    }
}a[maxn];
ll re;
int ttt;

int main()
{
    read(n);
    for(int i=1;i<=n;i++) read(a[i].y);
    for(int i=1;i<=n;i++) read(a[i].x);
    sort(a+1,a+n+1);

    for(int i=1;i<=n;i++)
    {
        ttt+=a[i].y;
        re+=(ll)a[i].x*ttt;
    }
    printf("%lld\n",re);

    return 0;
}

你可能感兴趣的:(BZOJ,多校,贪心,数学)