题目描述

出于某些方面的需求,我们要把一块N×M的木板切成一个个1×1的小方块。

对于一块木板,我们只能从某条横线或者某条竖线(要在方格线上),而且这木板是不均匀的,从不同的线切割下去要花不同的代价。而且,对于一块木板,切割一次以后就被分割成两块,而且不能把这两块木板拼在一起然后一刀切成四块,只能两块分别再进行一次切割。

现在,给出从不同的线切割所要花的代价,求把整块木板分割成1×1块小方块所需要耗费的最小代价。

输入输出格式

输入格式:

输入文件第一行包括N和M,表示长N宽M的矩阵。

第二行包括N-1个非负整数,分别表示沿着N-1条横线切割的代价。

第三行包括M-1个非负整数,分别表示沿着M-1条竖线切割的代价。

输出格式:

输出一个整数,表示最小代价。

解题思路

想像一下:

每横着切一刀后,竖着就要多切一刀,竖着切的代价就会变大一倍

每竖着切一刀后,横着就要多切一刀,横着切的代价就会变大一倍


所以很容易想到一种贪心的算法:

先将横着和竖着切的代价从大到小排序

将代价大的先切(这样切一次增加的代价就小一些)

直到全部切完


见代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,a[2005],b[2005],heng=0,shu=0;
long long ans=0;
bool cmp(const int x,const int y){return x>y;}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<m;i++)
        scanf("%d",&b[i]);
    sort(a+1,a+n,cmp);
    sort(b+1,b+m,cmp);
    while(heng!=n&&shu!=m)
    {
        if(a[heng+1]>=b[shu+1])
        {
            ans+=a[heng+1]*(1+shu);
            heng++;
        }
        else {
            ans+=b[shu+1]*(1+heng);
            shu++;
        }
    }
    while(heng!=n||shu!=m)
    {
        if(heng!=n)
        {
            ans+=a[heng+1]*(1+shu);
            heng++;
        }
        else {
            ans+=b[shu+1]*(1+heng);
            shu++;
        }
    }
    printf("%lld",ans);
    return 0;
}

留下评论