房屋分拆
题目描述:
厂长买了一整间房屋作为车间,现准备将整个房屋分成若干个车间。装修公司规定分拆房屋的价格等于被分拆房屋的面积。如想将面积为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;
}