結果

問題 No.393 2本の竹
ユーザー KilisameKilisame
提出日時 2016-09-14 10:23:33
言語 Java21
(openjdk 21)
結果
TLE  
実行時間 -
コード長 4,338 bytes
コンパイル時間 4,022 ms
コンパイル使用メモリ 84,276 KB
実行使用メモリ 308,528 KB
最終ジャッジ日時 2024-11-17 05:54:09
合計ジャッジ時間 54,527 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 TLE -
testcase_01 AC 176 ms
50,184 KB
testcase_02 TLE -
testcase_03 TLE -
testcase_04 AC 240 ms
58,928 KB
testcase_05 AC 786 ms
224,828 KB
testcase_06 AC 193 ms
51,784 KB
testcase_07 TLE -
testcase_08 TLE -
testcase_09 TLE -
testcase_10 TLE -
testcase_11 TLE -
testcase_12 TLE -
testcase_13 TLE -
testcase_14 TLE -
testcase_15 AC 312 ms
64,096 KB
testcase_16 WA -
testcase_17 TLE -
testcase_18 TLE -
testcase_19 WA -
testcase_20 AC 178 ms
269,076 KB
testcase_21 TLE -
testcase_22 TLE -
testcase_23 TLE -
testcase_24 TLE -
testcase_25 AC 217 ms
49,440 KB
testcase_26 AC 158 ms
43,548 KB
testcase_27 TLE -
権限があれば一括ダウンロードができます

ソースコード

diff #

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class TwoBamboo {

    /* メモ化用Map */
    private static Map<Long, Integer> calculatedMap;

    /* 2本の竹をそれぞれ2つのナップサックと考えて、ナップサック問題の動的計画法+メモ化で解く? */
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int d = cin.nextInt();
        int[][][] allQuestions = new int[d][2][];
        for (int i = 0; i < d; i++) {
            /* 2本の竹情報 */
            allQuestions[i][0] = new int[2];
            allQuestions[i][0][0] = cin.nextInt();
            allQuestions[i][0][1] = cin.nextInt();
            /* 要求数 */
            int requestsNum = cin.nextInt();
            /* 要求情報 */
            allQuestions[i][1] = new int[requestsNum];
            for (int j = 0; j < requestsNum; j++) {
                allQuestions[i][1][j] = cin.nextInt();
            }
        }
        calculatedMap = new HashMap<Long, Integer>();
        for (int[][] question : allQuestions) {
            System.out.println(answer(question[0], question[1]));
        }
    }

    /* 各データセット単位で解く */
    private static int answer(int[] bamboo, int[] requests) {
        /* 2本の竹の総和に対し、要求された長さを小さい順に足していく。要求された長さの和が2本の竹の総和を越えたら、以降の要求には絶対に応えられないので無視する。また、長いほうの竹を越える要求も満たせないので無視する */
        Arrays.sort(requests);
        int lengthSum = bamboo[0] + bamboo[1];
        int maxRequestLength;
        int requestSum = 0;
        for (maxRequestLength = 0; maxRequestLength < requests.length; maxRequestLength++) {
            requestSum += requests[maxRequestLength];
            if (requests[maxRequestLength] > bamboo[1] || requestSum > lengthSum) {
                break;
            }
        }
        requests = Arrays.copyOf(requests, maxRequestLength);
        calculatedMap.clear();
        return getNum(0, bamboo, requests);
    }

    private static int getNum(int currentIndex, int[] bamboo, int[] requests) {
        /* 最後の要求まで達したなら終了 */
        if (currentIndex >= requests.length) {
            return 0;
        }
        /* 竹の長さは変わっている可能性があるのでソートする */
        Arrays.sort(bamboo);
        /* 要求される長さが短い順にソートしているので、長い方の竹からでも切り出せない場合、それ以降切り出すことはできないので終了 */
        if (requests[currentIndex] > bamboo[1]) {
            return 0;
        }
        /* メモ化のキーは、現在のインデックスと2本の竹の残りの長さ */
        long key = currentIndex * 1000000L * 1000000L + bamboo[0] * 1000000L + bamboo[1];
        if (calculatedMap.containsKey(key)) {
            /* 計算済みなら返却 */
            return calculatedMap.get(key);
        }
        /* 切らないケース */
        int result = getNum(currentIndex + 1, bamboo, requests);

        /* 長い方から切り出すケース */
        int[] cutOfLongBamboo = Arrays.copyOf(bamboo, bamboo.length);
        cutOfLongBamboo[1] -= requests[currentIndex];
        int cutOfLongBambooNum = 1 + getNum(currentIndex + 1, cutOfLongBamboo, requests);
        if (cutOfLongBambooNum > result) {
            result = cutOfLongBambooNum;
        }

        if (requests[currentIndex] <= bamboo[0]) {
            int[] cutOfShortBamboo = Arrays.copyOf(bamboo, bamboo.length);
            cutOfShortBamboo[0] -= requests[currentIndex];
            int cutOfShortBambooNum = 1 + getNum(currentIndex + 1, cutOfShortBamboo, requests);
            if (cutOfShortBambooNum > result) {
                result = cutOfShortBambooNum;
            }
        }
        calculatedMap.put(key, result);
        return result;

    }

    private static void debug(int[] bamboo, int[] requests) {
        System.out.println("bamboo: a=" + bamboo[0] + ", b=" + bamboo[1]);
        for (int request : requests) {
            System.out.print(request + " ");
        }
        System.out.println();
    }
}
0