题目描述
出于某些方面的需求,我们要把一块N×M的木板切成一个个1×1的小方块。
对于一块木板,我们只能从某条横线或者某条竖线(要在方格线上),而且这木板是不均匀的,从不同的线切割下去要花不同的代价。而且,对于一块木板,切割一次以后就被分割成两块,而且不能把这两块木板拼在一起然后一刀切成四块,只能两块分别再进行一次切割。
现在,给出从不同的线切割所要花的代价,求把整块木板分割成1×1块小方块所需要耗费的最小代价。
输入格式
输入文件第一行包括N和M,表示长N宽M的矩阵。
第二行包括N-1个非负整数,分别表示沿着N-1条横线切割的代价。
第三行包括M-1个非负整数,分别表示沿着M-1条竖线切割的代价。
输出格式
输出一个整数,表示最小代价。
输入输出样例
输入 #1
2 2
3
3
输出 #1
9
说明/提示
数据范围:
对于60%的数据,有1 ≤ N ,M≤ 100;
对于100%的数据,有1 ≤ N,M ≤ 2000。
前言:这是什么水题啊,随便一打就过了
解法:贪心
-
因为我们需要把一个木板切为全部为1 * 1的,所以我们不管怎么切,结果是一样的,但是如果把花费更高的放到后面,肯定他需要的切的也会更多,所以我们先按花费从大到小排好序,这样花费是最小的
-
我们再定义两个变量,分别记录横着的木块有几个和竖着的木块有几个,这样后面切的话,如果是竖着切就乘上横着的块,再把竖着的块+1
-
反手加上一个register和快读,可以更优
AC代码
#include<cstdio>
#include<algorithm>
#define re register int
using namespace std;
struct node {
int x,id;
}e[4004];
int n,m,h=1,z=1,cnt;
long long ans;
inline int read() {
int x=0,cf=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') cf=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*cf;
}
inline bool cmp(node a,node b) {
if(a.x==b.x) return a.id<b.id;
return a.x>b.x;
}
int main() {
n=read(),m=read();
for(re i=1;i<n;i++) {
e[++cnt].id=1;
e[cnt].x=read();
}
for(re i=1;i<m;i++) {
e[++cnt].id=2;
e[cnt].x=read();
}
sort(e+1,e+cnt+1,cmp);
for(re i=1;i<=cnt;i++) {
if(e[i].id==1) {
ans+=e[i].x*h; z++;
}
else {
ans+=e[i].x*z; h++;
}
}
printf("%lld",ans);
return 0;
}