C语言 房屋分拆

房屋分拆

题目描述:

厂长买了一整间房屋作为车间,现准备将整个房屋分成若干个车间。装修公司规定分拆房屋的价格等于被分拆房屋的面积。如想将面积为200的房间分拆为面积为80、70和50的三个车间,第一次将房屋分拆为面积120和80的两个房间,花费200,第二次将面积为120的房间分拆为面积为70和50的两个房间,花费120,总花费为320。如果采用另一种方案,第一次将面积200的房屋分拆为150和50,花费200,第二次将面积为150的房间分拆为80和70的房间,花费150,则总花费为350。显然第一种方案花费更少。请编写程序为厂长设计花费最少的分拆方案。
输入格式:
输入为两行,第一行为一个整数n,表示所需的车间数量。第二行为n个正整数,以空格间隔,给出每个车间需要的面积。n不超过100000,且保证最终结果小于2> ​31 ​​ 。
输出格式:
输出为一个整数,表示将整个房屋分拆为n个车间所需的最少花费。

输入样例:

8 1 1 1 1 2 3 4 5

输出样例:

49

代码如下:

#include<stdio.h>
#include<stdlib.h>
typedef struct Node * Heap; /*堆结构*/
struct Node
{
	int * Data;
	int Size;
};
typedef Heap MinHeap;/*最小堆*/
Heap CreateHeap(int n)//最小堆的创建
{
	MinHeap H=(MinHeap)malloc(sizeof(struct Node));
	H->Data=(int *)malloc(2*(n+1)*sizeof(int));
	H->Size=0;//初始化 
	H->Data[0]=0;/*最小堆的哨兵*/
	return H;
}
void Insert(Heap H,int m)//建初堆
{
	int i;
	i=++H->Size;
	for(; H->Data[i/2]>m; i/=2)
		H->Data[i]=H->Data[i/2];
	H->Data[i]=m;
}
int Del(Heap H)//重建小跟堆
{
	int parent,child;
	int min,x;
	min=H->Data[1];
	x=H->Data[H->Size--];//用最后一个元素替代已经输出的堆顶元素
	for(parent=1; parent*2<=H->Size ; parent=child) //沿较小的孩子向下筛选{
	{
   	child=parent*2;
	if((child!=H->Size)&&(H->Data[child]>H->Data[child+1])) child++;
	if(H->Data[child]>=x) break;
	else H->Data[parent]=H->Data[child];
   }
H->Data[parent]=x;
return min;
}
int main()
{
	int n,m,i,sum=0,a,b;
	scanf("%d",&n);
	Heap H=CreateHeap(n);
	for(i=1; i<=n; i++)
	{
		scanf("%d",&m);
		Insert(H,m);/*将所有元素入堆(H)*/
	}
	while(H->Size!=1)
	{
		a=Del(H);//去掉最小值再重建堆
		b=Del(H);//去掉次小值再重建堆
		b=a+b;
		sum+=b;//不断累加求和
		Insert(H,b);
	}
	printf("%d\n",sum);
	system("pause");
	return 0; 
}
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值