https://paiza.jp/poh/kirishima/
あなたとJava
- chokudai氏の「ダイナミック・プログラミン」しか頭に浮かばなかった
- 一次元DPでよいです
import java.util.*;
public class Main {
static void solve() throws Exception {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[] q = new int[n];
int[] r = new int[n];
for (int i = 0; i < n; i++) {
q[i] = sc.nextInt();
r[i] = sc.nextInt();
}
// dp[k] : k人集めたときに一番安い組み合わせ
int[] dp = new int[m + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
// 各業者、各セル
for (int i = 0; i < n; i++) {
for (int k = m - 1; k >= 0; k--) {
if (dp[k] == Integer.MAX_VALUE) continue;
// その業者を使って dp[j] が安く出来るなら更新
int j = Math.min(m, k + q[i]);
dp[j] = Math.min(dp[j], dp[k] + r[i]);
}
}
// 全業者に対して試行後、最終版の dp[m] が答えになる
System.out.println(dp[m]);
}
public static void main(String[] args) throws Exception {
solve();
}
}
結果 : https://paiza.jp/poh/kirishima/result/6728ece1f8ddf7ec3d862e3059bfb67f
BufferedReader最高だと思ったが、uwi氏が作っていたbyte[]から直接読む奴を作ってみようと思った。
static InputStream is;
private static byte[] _ib = new byte[1024];
static int _p = 0, _l = 0;
// read one byte
private static int _rb() throws Exception {
if (_l < 0) return -1;
if (_p >= _l) {
_p = 0;
_l = is.read(_ib);
if (_l <= 0) return -1;
}
return _ib[_p++];
}
// positive integer
private static int _psi() throws Exception {
int num = 0, b;
while ((b = _rb()) > 0 && !(b >= '0' && b <= '9')) ;
do {
num = num * 10 + (b - '0');
} while ((b = _rb()) > 0 && b >= '0' && b <= '9');
return num;
}
結果:http://paiza.jp/poh/kirishima/result/4863aa05872a6dae7354ef0bf6836f4d
全ケースで最速+-10msに収まる。Case6で最速塗り替えることが出来たけどまあ誤差っぽいので妥当な解法っぽい。
static InputStream is;
private static byte[] _ib = new byte[1024];
static int _p = 0, _l = 0;
private static void readAll() throws Exception {
_p = 0;
_l = is.read(_ib);
}
// positive integer
private static int _psi() throws Exception {
int num = 0, b;
while ((b = _ib[_p++]) > 0 && !(b >= '0' && b <= '9')) ;
do {
num = num * 10 + (b - '0');
} while ((b = _ib[_p++]) > 0 && b >= '0' && b <= '9');
return num;
}
こんな感じで readAll() を初回に1度だけ呼ぶことで、深い関数呼び出しを回避して、
スタック生成/除去のタイムラグを減らす。
結果 : http://paiza.jp/poh/kirishima/result/8e66e51376db1407bb1fbf10c2c32dfe
最大ケースで最速タイ。
後ろの席で同僚が言語最速出してた