洛谷 P1324 矩形分割 贪心

题目描述
出于某些方面的需求,我们要把一块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的,所以我们不管怎么切,结果是一样的,但是如果把花费更高的放到后面,肯定他需要的切的也会更多,所以我们先按花费从大到小排好序,这样花费是最小的

  2. 我们再定义两个变量,分别记录横着的木块有几个和竖着的木块有几个,这样后面切的话,如果是竖着切就乘上横着的块,再把竖着的块+1

  3. 反手加上一个register和快读,可以更优

AC代码

#include
#include
#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;
}

你可能感兴趣的:(贪心)