[POJ3253]Fence Repair(单调队列)

题目链接

http://poj.org/problem?id=3253

题目描述

大意:切长度为a的木条的花费是a,给定最终切好的n段各自的长度,问由原来的一根木条(长度为n段长度和)以最终总花费最小的方法切这n-1下,输出最小花费。(切的中间过程产生的子段不同,所以花费会不同)

例子:
输入:
3
8 5 8
输出:
34
提示:
(8+5)+(13+8)=34

题解

  • 过程反着想,就是合并子段的过程。
  • 数据结构:两个单调递增队列。
    • 第一个放进原始的n段的长度。
    • 第二个用来放合并后的段的长度。
    • 每次贪心地选择两个队列头最小的两个段合并。合并后放入队列2头部,可以知道队列2也是单调递增的。

代码

import java.util.LinkedList;
import java.util.Scanner;

public class Main {
	public static void main(String args[]) {
		Scanner in = new Scanner(System.in);
		int n=in.nextInt();
		LinkedList<Integer> q=new LinkedList<Integer>();
		while(n--!=0) {
			q.addLast(in.nextInt());
		}
		int cost=getMinCost(q);
		System.out.println(cost);
	}
	
	public static int getMinCost(LinkedList<Integer> q) {
		q.sort(null);
		int n=q.size()-1;//切(合并)的次数
		LinkedList<Integer> sumQue=new LinkedList<>();
		int sum=0;
		while(n--!=0) {
			int tempSum=0;
			int cnt=2;
			while(cnt--!=0) {
				if(sumQue.isEmpty()||(!sumQue.isEmpty()&&!q.isEmpty()&&q.peekFirst()<=sumQue.peekFirst())) {
					tempSum+=q.pollFirst();
				}
				else {
					tempSum+=sumQue.pollFirst();
				}
			}
			sum+=tempSum;
			sumQue.addFirst(tempSum);
		}
		return sum;
	}
}

posted on   coding_gaga  阅读(105)  评论(0编辑  收藏  举报

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示