PAT修理牧场

农夫需要将一根长木头锯成N块来修理牧场栅栏,每块木头长度已知。锯木头的费用与其长度成正比。问题求解最小总费用。给定木头需锯成的块数和各块长度,程序需计算最低成本。
摘要由CSDN通过智能技术生成

题目:

农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要NNN块木头,每块木头长度为整数LiL_iLi个长度单位,于是他购买了一条很长的、能锯成NNN块的木头,即该木头的长度是LiL_iLi的总和。

但是农夫自己没有锯子,请人锯木的酬金跟这段木头的长度成正比。为简单起见,不妨就设酬金等于所锯木头的长度。例如,要将长度为20的木头锯成长度为8、7和5的三段,第一次锯木头花费20,将木头锯成12和8;第二次锯木头花费12,将长度为12的木头锯成7和5,总花费为32。如果第一次将木头锯成15和5,则第二次锯木头花费15,总花费为35(大于32)。

请编写程序帮助农夫计算将木头锯成NNN块的最少花费。

输入格式:

输入首先给出正整数NNN≤104\le 10^4104),表示要将木头锯成NNN块。第二行给出NNN个正整数(≤50\le 5050),表示每段木块的长度。

输出格式:

输出一个整数,即将木头锯成NNN块的最少花费。

输入样例:

8
4 5 1 2 1 3 1 1

输出样例:

49
 

C++:

#include<iostream>
using namespace std;

//链表结点
typedef struct TreeNode
{
	int data;
	struct TreeNode *next;
}TreeNode,* LinkList;

//构造最优树
void CreateBestTree(LinkList &list,int *childNode,int length)
{
	if(childNode==NULL||length<0)
		return;
	LinkList temp=list;
	for(int i=0;i<length;i++)
	{
		TreeNode *newNode=new TreeNode;
		newNode->data=childNode[i];
		newNode->next=NULL;
		if(list==NULL)
			list=newNode;
		else
			temp->next=newNode;
		temp=newNode;
	}
}

//快速排序
void QuitSort(int *data,int low,int high)
{
	if(low<high)
	{
		int start=low,end=high,save=data[low];
		while(start<end)
		{
			while(start<end&&data[end]>save) end--;
			if(start<end)
				data[start++]=data[end];
			while(start<end&&data[start]<save) start++;
			if(start<end)
				data[end--]=data[start];
		}
		data[start]=save;
		QuitSort(data,low,start-1);
		QuitSort(data,start+1,high);
	}
}

//插入到有序链表

void InsertLinkList(LinkList &list,int elem)
{
	if(list==NULL)
		return;
	TreeNode *temp=list;
	LinkList node=new TreeNode;
	node->data=elem;
	node->next=NULL;
	while(temp->next)
	{
		if(temp->data>elem)  //插入到表头
		{
			node->next=list;
			list=node;
			return;
		}
		else if(temp->data<elem&&(temp->next->data>=elem))  //中间位置
		{
			node->next=temp->next;
			temp->next=node;
			return;
		}
		else
			temp=temp->next;
	}
	temp->next=node;  //插入到表尾
}

int GetMinValue(LinkList &list)
{
	int minValue=0,sum=0;
	LinkList node1=NULL,node2=NULL;
	while(list&&list->next)
	{
		node1=list;
		node2=list->next;
		sum=node1->data+node2->data;
		minValue+=sum;  //计算总和
		list=list->next->next;
		free(node1);
		free(node2);
		InsertLinkList(list,sum);
	}
	return minValue;
}

int main()
{
	LinkList list=NULL;
	int count;
	cin>>count;
	int *base=new int[count];
	for(int i=0;i<count;i++)
		cin>>base[i];
	QuitSort(base,0,count-1);
	CreateBestTree(list,base,count);
	cout<<GetMinValue(list);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值