0
0

More than 1 year has passed since last update.

paizaラーニング レベルアップ問題集 DPメニュー JavaScript 最長部分増加列

Posted at

最長部分増加列 (paizaランク B 相当)

解答例

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [n] = lines[0].split(" ").map(Number);
const a = lines.slice(0).map(Number);//木iとa[i]をそろえた
a[0] = 0;//木0は0としておく。

const dp = Array(n + 1).fill(0);//dp[i]は最後が木 i であるような増加部分列のうち最長であるものの長さ。これを登録していく。nまでなので長さn+1のArray(n+1)にする。

dp[1] = 1;//木iのdp[1]は1
for (let i = 2; i <= n; i++) { //木2から木nまで見ていく
  //木iに注目する
  dp[i] = 1; // 木 i のみからなる部分列の長さ。もし木iより小さい全ての木が大きかったら、dp[i]=1なので、これを初期値とすル。
  //木iと、より小さい木jの高さを比較していく
  for (let j = 1; j <= i - 1; j++) { //jはiより小さい木の添字
    if (a[j] < a[i]) { //もし木jが木iより小さかったら
      //dp[i]は、最後が木i であるような増加部分列のうち最長であるものの長さ
      dp[i] = Math.max(dp[i], dp[j] + 1); // 最後が木 j であるような増加部分列の末尾に木 i をくっつける → dp[j] + 1
      //Math.max(dp[i], dp[j] + 1)の dp[i]は、最後が木iであるような増加部分列の今まで更新してきた中で一番長い長さ
      //dp[j] + 1は最後が木 j であるような増加部分列の末尾に木 i をくっつけた長さ
      //dp[j]は木jによって変わり、常にdp[j]+1>dp[i]ではないので、dp[i]と大きさを比較する必要があるからMath.max()
    }
  }
}
console.log(dp.reduce((a, b) => Math.max(a, b)));
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0