2012-04-27 32 views
6

Tôi đã cố gắng suy nghĩ từ HOURS về vấn đề TopCoder này và không thể đi kèm với một giải pháp hoàn hảo làm việc và tìm thấy một đưa ra dưới đây là điên rồ đẹp được sử dụng!Tại sao mã này hoạt động cho trình thăm dò TopCoder này?

Tôi đang cố gắng tìm ra cách giải pháp này hoạt động đối với probem đã cho? Và làm thế nào tôi có thể nghĩ ban đầu về nó? Sau khi đọc giải pháp tôi đã nhận ra đó là một biến thể của mã Huffman nhưng đó là điều tôi có thể nhận được. Tôi thực sự say mê và muốn biết những gì dòng suy nghĩ có thể dẫn đến giải pháp này ..

Dưới đây là các vấn đề: http://community.topcoder.com/stat?c=problem_statement&pm=11860&rd=15091

Fox Ciel có rất nhiều bài tập về nhà để làm. Bài tập về nhà bao gồm một số nhiệm vụ cùng nhau độc lập. Các nhiệm vụ khác nhau có thể lấy các số tiền khác nhau thời gian để hoàn thành. Bạn được cung cấp một int [] workCost. Đối với mỗi i, nhiệm vụ thứ i là sẽ mất tối đa [i] giây để hoàn thành. Cô ấy muốn tham dự một bữa tiệc và gặp gỡ bạn bè của cô ấy, do đó cô ấy muốn hoàn thành tất cả các nhiệm vụ nhanh nhất có thể.

Vấn đề chính là tất cả các con cáo, kể cả Ciel, thực sự ghét làm bài tập về nhà . Mỗi con cáo chỉ sẵn sàng làm một trong các nhiệm vụ. May mắn thay, Đôrêmon, một con mèo robot từ thế kỷ 22, đã cho Fox Ciel một cái búa chia tách : một tiện ích ma thuật có thể tách bất kỳ con cáo nào thành hai con cáo.

Bạn được cung cấp một phân tách int. Sử dụng búa tách trên con cáo là tức thời. Khi một cái búa được sử dụng trên một con cáo, con cáo sẽ bắt đầu tách ra là . Sau khi splitCost giây cô sẽ biến thành hai con cáo - con cáo ban đầu và một con cáo hoàn toàn mới. Trong khi một con cáo đang tách ra, nó không được phép sử dụng cây búa trên cô ấy một lần nữa.

Công việc trên một tác vụ không thể bị gián đoạn: một khi con cáo bắt đầu làm việc trên một nhiệm vụ, cô ấy phải hoàn thành nó. Nó không được phép cho nhiều con cáo để hợp tác trên cùng một nhiệm vụ. Con cáo không thể thực hiện nhiệm vụ khi cô ấy đang bị chia nhỏ bằng búa. Có thể chia cùng một con cáo nhiều lần. Có thể chia một con cáo cả trước và sau cô ấy giải quyết một trong các nhiệm vụ.

Tính toán và trả lại khoảng thời gian nhỏ nhất mà các cáo có thể giải quyết tất cả các tác vụ.

Và đây là giải pháp tôi tìm thấy tại đây link

import java.util.*; 

public class FoxAndDoraemon { 
    public int minTime(int[] workCost, int splitCost) { 
    PriorityQueue<Integer> pq = new PriorityQueue<Integer>(); 

    for(int i : workCost) pq.offer(i); 

    while(pq.size()>=2) { 
     int i = pq.poll(); 
     int j = pq.poll(); 
     pq.offer(Math.max(i, j) + splitCost); 
    } 
    return pq.poll(); 

    } 
} 
+0

Hàng đợi ưu tiên có trả về phần tử tối đa hoặc phần tử min khi bạn thăm dò ý kiến ​​không? – ElKamina

+0

Ít nhất. Hàng đợi ưu tiên được sắp xếp từ ít nhất đến phần tử lớn nhất và giữ lại phân loại của chúng trên chèn. – Charles

+2

Câu trả lời này có vẻ không chính xác. Hãy xem xét 'minTime (new int [] {1, 1, 1}, 5)'. Rõ ràng điều đúng đắn cần làm là không song song với bất kỳ nhiệm vụ nào, do đó phải mất 3 giây. Giải pháp này sẽ cung cấp cho 11s! –

Trả lời

6

Trước hết bạn làm nhận ra lý do đằng sau 'max (i, j) + splitCost'. Phải không? Về cơ bản, nếu bạn có một con cáo, bạn chia nó thành hai và thực hiện từng tác vụ một cách độc lập. Chúng ta hãy gọi quá trình này là "sáp nhập".

Giả sử chúng tôi có ba công việc a, b và c sao cho a> b> c. Bạn có thể làm hợp nhất (hợp nhất (a, b), c) hoặc hợp nhất (hợp nhất (a, c), b) hoặc hợp nhất (hợp nhất (b, c), a). Làm toán và bạn có thể chứng minh rằng hợp nhất (hợp nhất (b, c), a) là ít nhất trong số ba.

Bây giờ bạn có thể sử dụng cảm ứng để chứng minh rằng giải pháp này là hợp lệ cho bất kỳ số lượng công việc nào (không chỉ 3).

+0

giải thích tuyệt vời! – soulcheck

3

Nó đang xây dựng một cây từ mặt đất lên.

Thuật toán sử dụng một thực tế cơ bản để làm việc: Nếu bạn loại bỏ hai phần tử nhỏ nhất, chi phí tính toán phần tử nhỏ nhất luôn nhỏ hơn chi phí của phần tử nhỏ nhất tiếp theo cộng với phân chia. (Xem bài đăng của ElKamina để có bằng chứng kỹ lưỡng hơn về điều này). Vì vậy, nếu bạn chỉ có hai yếu tố trong cây của bạn (nói 4 và 2) và chi phí phân chia của bạn là 4, số lượng thời gian thấp nhất luôn là 8 (bên cạnh yếu tố nhỏ nhất cộng với chi phí chia tách.).

Vì vậy, để xây dựng cây của chúng tôi: giả sử chúng tôi đã nhận workCost [1,3,4,5,7,8,9,10], và splitCost của chúng tôi là 3.

Vì vậy, chúng ta nhìn vào hai yếu tố nhỏ nhất: 1,3. 'Chi phí' của máy tính này là tối thiểu 6 (số lớn nhất cộng với chi phí của một phần chia. Sau đó, đưa 6 vào hàng đợi, về cơ bản bạn sẽ thêm cây con:

6 
1 3 

Trường hợp 'chiều cao'/'chi phí' là 6 tổng. Bằng cách lặp lại quá trình này, bạn sẽ xây dựng một cây bằng cách sử dụng các phần con nhỏ nhất mà bạn có thể (hoặc là một cây con hiện có hoặc một bài tập về nhà chưa hoàn thành mới).

Giải pháp cuối cùng sẽ trông như thế này: (Nơi S (X) là chi phí của tách cộng giải quyết tất cả mọi thứ dưới nó)

    S(17) 
      S(13)  S(14) 
     S(10)  9 10  S(11) 
    S(6)  7   S(8)  8 
1  3     4 5 

Nếu bạn theo dõi ngược lên cây này, thật dễ dàng để xem cách công thức giải quyết nó: chi phí của 1 và 3 là S (6), 4 và 5 là S (8), sau đó S (6) và 7 là S (10), 8 và S (8) là S (11), v.v.

Các vấn đề liên quan