矩形分割(洛谷 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

这道题思维+贪心;首先我们要知道每次切割用的费用不同,这也意味着我们要先切费用大的那个点。知道了这个,我们还要知道切了一刀后,如果竖着切,那么横着切的点要再切一次,因为分成了两个矩形;横着切同理;一个点只能切一次

代码:

#include
using namespace std;
struct Node{
	int post,date;
}dian[40000];
bool cmp(Node p,Node q){
	return p.date>q.date;
}
int a[40000];
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	int ans=0;
	for(int i=1;i<=n-1;i++){
		scanf("%d",&dian[++ans].date);
		dian[ans].post=ans;
	}
	for(int i=1;i<=m-1;i++){
		scanf("%d",&dian[++ans].date);
		dian[ans].post=ans;
	}
	sort(dian+1,dian+1+ans,cmp);
	for(int i=1;i<=ans;i++) a[i]=1;//初始每个点只能切一次
	long long sum=0;
	for(int i=1;i<=ans;i++){
		if(a[dian[i].post]==0) continue;//已经切过
		sum=sum+(long long)a[dian[i].post]*(long long)dian[i].date;
		a[dian[i].post]=0;
		if(dian[i].post>=n){
			for(int j=1;j<n;j++){//长度上的点
				if(a[j]==0) continue;
				a[j]++;
			}
		}
		else{
			for(int j=n;j<=ans;j++){//宽度上的点
				if(a[j]==0) continue;
				a[j]++;
			}
		}
	}
	cout<<sum<<endl;
    return 0;
}

你可能感兴趣的:(#,贪心,#,思维)