题目描述
出于某些方面的需求,我们要把一块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;
}