POH Lite 天才火消しエンジニア霧島 3.33秒
※ 実際のプロジェクトではこの様には行きませんので、人員を増やす場合は慎重に検討する事をお勧めいたします。
1万円の下請けってどんなところなんだろうか。
まあ典型的なナップザック問題なので、さっくり解いてしまいましょう。
<?php
// 入力をパース
$input = file('php://stdin', FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
// 1行目は必要人数
$ninzuu = (int)$input[0];
// 2行目は会社数 使わない
// $kaishasuu = (int)$input[1];
// 3行目以降は人数+価格 最大50社しかない
unset($input[0]);unset($input[1]);
$list = array_map(function($a){
// 0=>人数,1=>価格
$t=explode(' ', $a, 2);
return [(int)$t[0],(int)$t[1]];
}, $input);
// 動的計画法
$data = [0=>0];
foreach($list as $key1=>$val1){
// 1社で越えている場合は0にだけ足せばいい
if($val1[0]>=$ninzuu){
if(isset($data[$val1[0]])){
$data[$val1[0]] = min($data[$val1[0]], $val1[1]);
}else{
$data[$val1[0]] = $val1[1];
}
continue;
}
foreach($data as $key2=>$val2){
// 既に人数を越えている場合は計算不要
if($key2 >= $ninzuu){ continue; }
// 対象人数の金額を登録
$num = $key2+$val1[0];
if(isset($data[$num])){
// 既に値がある場合は安い方
$data[$num] = min($data[$num], $val2+$val1[1]);
}else{
$data[$num] = $val2+$val1[1];
}
}
}
// 最低人数越えのキーのうち、最低金額のものを選択
$minTotal = 250000000;
foreach($data as $key=>$val){
if($key >= $ninzuu && $val < $minTotal ){
$minTotal = $val;
}
}
print($minTotal . PHP_EOL);
普通に動的計画法を適用しただけです。
実に簡単ですね。
人数をキーにしたせいで動的計画法というより総当たりになってしまった気もしますがまあいいや。
さっそく実行。
https://twitter.com/rana_kualu/status/495214956573229056
http://paiza.jp/poh/kirishima/result/bebdc876df9e6cd24b4ee916a06eeea3
Test case 1 | 通過 | 実行時間: 0.01 秒 |
Test case 2 | 通過 | 実行時間: 0.01 秒 |
Test case 3 | 通過 | 実行時間: 0.01 秒 |
Test case 4 | 通過 | 実行時間: 0.01 秒 |
Test case 5 | 通過 | 実行時間: 0.01 秒 |
Test case 6 | 通過 | 実行時間: 0.27 秒 |
Test case 7 | 通過 | 実行時間: 3.33 秒 |
あっさり合格しました。
めでたし。
まあ、実はここに辿り着くまでに2回も失敗しているのですが。
https://twitter.com/rana_kualu/status/494452573533773825
http://paiza.jp/poh/kirishima/result/4f809703f962fdb735dd00dd83943b22
最初、何も考えずに『単価の安い順に足していく』という頭の悪すぎる実装をやってしまいテスト5で失敗。
10人でいいプロジェクトに単価の安い100人を送り込まれてもねえ。
https://twitter.com/rana_kualu/status/494821947201421312
http://paiza.jp/poh/kirishima/result/a5ec246afdb9c754e44f003bae62ab97
まじめに考えてきちんと動的計画法を適用したのに何故かテスト7だけ失敗。
その日は何処にも間違う要素無いだろうがーなんでだーと延々悩んで結局答えが出なかったのですが、翌日見直してみたら
$minTotal = 5000000;
とか書いてあって即死。
いやあこれは酷い。
さてこのアルゴリズム、テスト7では3秒以上かかっていますが、PHPで既に0.01秒というおかしな値が達成されています。
いったい果たしてどんな書き方がなされているのでしょうか。
Author And Source
この問題について(POH Lite 天才火消しエンジニア霧島 3.33秒), 我々は、より多くの情報をここで見つけました https://qiita.com/rana_kualu/items/9c082ecb59cba0ba9bce著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .