POJ1339(哈夫曼树)

POJ1339(哈夫曼树)poker card gameDescriptionSuppose you are given many poker cards. As you have already known, each card has points ranging from 1 to 13. Using these poker cards, you need to play a game on the cardboard in Figure 1. The game begins with a p
摘要由CSDN通过智能技术生成

POJ1339(哈夫曼树)


poker card game

Description

Suppose you are given many poker cards. As you have already known, each card has points ranging from 1 to 13. Using these poker cards, you need to play a game on the cardboard in Figure 1. The game begins with a place called START. From START, you can walk to left or right to a rectangular box. Each box is labeled with an integer, which is the distance to START.

img
Figure 1: The poker card game cardboard.

To place poker cards on these boxes, you must follow the rules below: (1) If you put a card with n points on a box labeled i , you got (n ∗ i) points. (2) Once you place a card on a box b, you block the paths to the boxes behind b. For example, in Figure 2, a player places a queen on the right box of distance 1, he gets 1 ∗ 12 points but the queen also blocks the paths to boxes behind it; i.e., it is not allowed to put cards on boxes behind it anymore.

img
Figure 2: Placing a queen.

Your goal: Given a number of poker cards, find a way to place them so that you will get the minimum points. For example, suppose you have 3 cards 5, 10, and K. To get the minimum points, you can place cards like Figure 3, where the total points are 1 * 13 + 2 * 5 + 2 * 10 = 43.

img
Figure 3: An example to place cards.

Input

The first line of the input file contains an integer n, n <= 10, which represents the number of test cases. In each test case, it begins with an integer m, m <= 100000,

which represents the number of poker cards. Next, each card represented by its number are listed consecutively. Note that, the numbers of ace, 2, 3, …, K are given by integers 1, 2, 3, …, 13, respectively. The final minimum point in each test case is less than 5000000.

Output

List the minimum points of each test case line by line.

Sample Input

3
3
5 10 13
4
3 4 5 5
5
7 7 10 11 13

Sample Output

43
34
110
题意

​ 给出n长扑克,将扑克放入上图中框中,得分为扑克牌点数乘以空框到树根的距离,求最小得分。

思路

​ 已知树的叶子节点的值,求带权路径最小的树的路径长度。用哈夫曼树的思想求解。

代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class PokerCardGame {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            int m = sc.nextInt();
            int result = 0;
            List<Integer> nums = new ArrayList<Integer>();
            for (int j = 0; j < m; j++) {
                nums.add(sc.nextInt());
            }
            for (int j = 0; j < m - 1; j++) {
                int min1 = Integer.MAX_VALUE;
                int min2 = Integer.MAX_VALUE;
                int index1 = -1;
                int index2 = -1;
                for (int k = 0; k < nums.size(); k++) {
                    if (nums.get(k) < min1) {
                        min2 = min1;
                        index2 = index1;
                        min1 = nums.get(k);
                        index1 = k;
                    } else if (nums.get(k) < min2) {
                        min2 = nums.get(k);
                        index2 = k;
                    }
                }
                result = result + min1 + min2;
                nums.set(index1, min1 + min2);
                nums.remove(index2);
            }
            System.out.println(result);
        }
    }
}
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
升序队列,小顶堆
priority_queue<int,vector<int>,greater<int> >_queue;
int main()
{
  int m,n,num;
  scanf("%d",&n);
  while(n--)
  {
    scanf("%d",&m);
    while(_queue.empty()==false) _queue.pop();
    for(int i=0;i<m;i++)
    {
      scanf("%d",&num);
      _queue.push(num);
    }
    int result=0;
    while(_queue.size()>1)
    {
      int min1=_queue.top();
      _queue.pop();
      int min2=_queue.top();
      _queue.pop();
      result+=min1+min2;
      _queue.push(min1+min2);
    }
    cout<<result<<endl;
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值