zoukankan      html  css  js  c++  java
  • Fence Repair 栅栏分割

    题目:
    农夫约翰想修复牧场周围的一小部分篱笆。 他测量围栏,发现他需要N(1≤N≤20,000)块木板,每块木板具有一定的整数长度Li(1≤Li≤50,000)个单位。 然后,他购买了一块足够长的单块长板,足以切入N块木板(即,其长度为Li的长度之和)。 FJ忽略了“锯缝”,即锯切时因锯末而损失的额外长度; 您也应该忽略它。
    FJ遗憾地意识到自己没有切割木头的锯子,于是他用这长板把苔藓拖到农夫唐农场,礼貌地问他是否可以借用锯子。
    壁橱资本家农夫唐(Farmer Don)不借给FJ锯,而是提议就木板中的每个N-1切割向农夫约翰收费。 切割一块木头的费用正好等于它的长度。 切割一块长度为21的木板需要21美分。
    然后,农夫唐让农夫约翰决定切割木板的顺序和位置。 帮助农夫约翰确定他可以用来制作N块木板的最低金额。 FJ知道他可以按各种不同的顺序切割木板,这将导致不同的费用,因为最终的中间木板长度不同。

    思路:由于木板的切割顺序不确定,切割方法有很多,怎么找最小花费。。。
    我们可以利用二叉树原理来描述切割木板。要想总花销最小,可以使用哈夫曼树的特点,最短的板当做最深的叶子结点,构建哈夫曼树,最后的花费肯定是最小的。
    如何构造:
    1.将给出的几个长度从小到大排序
    2.取最短的两个合并,当做一个新的长板
    3.重复,直到最后组合成一个木板。
    但是每次最短两个木板相加后都需要整体排序,可能超时
    所以可以用STL,自动排序.

    #include <string.h>
    #include <stdio.h>
    #include <math.h>
    #include <queue>
    #include <stack>
    #include <algorithm>
    #define ll long long
    using namespace std;
    int main()
    {
    	int n,i,j,t,x;
    	while(~scanf("%d",&n)) 
    	{
    		priority_queue<int,vector<int>,greater<int> > q;
    		for (i=0;i<n;i++)
    		{
    			scanf("%d",&x);
    			q.push(x);
    		}
    		ll sum=0,a=0,b=0;
    		while(!q.empty())
    		{
    			a=q.top(),q.pop();
    			if (q.empty())
    			break;
    			b=q.top(),q.pop();
    			sum+=(a+b);
    			q.push(a+b);
    		}
    		printf("%lld
    ",sum);
    	}
    
    	return 0;
    }
    /*
    因为朴素的HuffmanTree思想是:
    (1)先把输入的所有元素升序排序,再选取最小的两个元素,把他们的和值累加到总费用
    (2)把这两个最小元素出队,他们的和值入队,重新排列所有元素,重复(1),
    直至队列中元素个数<=1,则累计的费用就是最小费用
    但是STL貌似有个自动排序呀
    */
  • 相关阅读:
    返回一个整数数组中最大子数组的和
    对autocad的建议
    作业:30道四则运算——C++编程
    四则运算2
    [leetcode] Letter Combinations of a Phone Number
    [leetcode] Pow(x, n)
    [leetcode] Longest Common Prefix
    [leetcode] Binary Tree Zigzag Level Order Traversal
    [leetcode] Construct Binary Tree from Preorder and Inorder Traversal
    [leetcode] Construct Binary Tree from Inorder and Postorder Traversal
  • 原文地址:https://www.cnblogs.com/shidianshixuan/p/14354184.html
Copyright © 2011-2022 走看看