結果
| 問題 |
No.393 2本の竹
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-09-14 10:23:33 |
| 言語 | Java (openjdk 23) |
| 結果 |
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 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 8 WA * 2 TLE * 18 |
ソースコード
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();
}
}