YKpages

ロボット分野で勉強したことのまとめ

AtCoder Beginner Contest 026 C - 今日から始める競技プロ日記

はじめに

chokudaiさんが今日の一問としてツイートしていたABC026のC問題を解いてみた。

14分で解いた。目標は20分だったのでまずまず良さげ。

高橋君の給料

社員がN人、社長の社員番号が1である。

社員番号2~Nの社員には必ず直属の上司が一人存在する。

直属の部下がいない社員の給料は1。

直属の部下がいる社員の給料は、max(直属の部下たちの給料) + min(直属の部下たちの給料) + 1。

社長の給料を求めよ。

解き方

末端の社員から給料を求めていけば、 最終的に社長の給料が求められるなーと考えた(当たり前だけど)。

そこで問題なのがどうやってデータを扱うか。

必要な情報はある社員にどんな部下がいるかということ。

ということでこんな感じにまとめてみる。

サンプル2の場合

社員数:7人

社員番号 直属の上司
1 なし
2 1
3 1
4 2
5 2
6 3
7 3

各社員の直属の部下たちをまとめる。

社員番号 直属の部下たち
1 2, 3
2 4, 5
3 6, 7
4 なし
5 なし
6 なし
7 なし

このようにまとめた後、社員番号が一番大きい社員の給料から求めていく。

社員番号7,6,5,4の社員は部下がいないので給料1。

社員番号3の社員の部下は6,7で、max=1, min=1だから、社員番号3の社員の給料は1+1+1=3。

同じように計算して社員番号2の給料は1+1+1=3。

そして最後に社長(社員番号1)の給料は3+3+1=7。

したがって出力すべき答えは7。

コード

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
        int N;
        cin >> N;
        vector<vector<int>> v(N+1);
        vector<int> c(N+1, 1);
        for(int i = 1; i < N; i++)
        {
                int a;
                cin >> a;
                v[a-1].push_back(i);
        }
 
        for(int i = N-1; i >= 0; i--)
        {
                if(v[i].size() == 0) continue;
                int maxv = 1;
                int minv = 1<<29;
                for(auto& t: v[i])
                {
                        maxv = max(maxv, c[t]);
                        minv = min(minv, c[t]);
                }
                c[i] = maxv + minv + 1;
        }
 
        cout << c[0] << endl;
        return 0;
}

おわりに

良問だった

今日から始める競プロ日記のまとめページ

kato-robotics.hatenablog.com