質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3035閲覧

区間スケジューリング問題の類似問題

spiii

総合スコア24

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/06/17 12:47

編集2020/06/17 13:18

はじめに

競技プログラミングについての質問ですが、paizaやある企業のコーディングテストに関連するものではありません。

問題概要

数直線状に(start_i, end_i)がいくつか与えられます。
区間スケジューリングでは、仕事の数を最大にする問題ですが、今回は重なっている区間の重なりの最大値を算出したいです。

自分のコード

vp[i].firstにその区間のstart地点
vp[i].secondにその区間のend地点を入れています。

c++

1 vector<pair<int, int>> vp; 2 int ans = 0; 3 for (int i = 0; i<vp.size(); i++){ 4 int cnt = 0; 5 int sx = vp[i].first; 6 int ex = vp[i].second; 7 for (int j=0; j<vp.size(); j++){ 8 if((vp[j].first <= sx && vp[j].second >= sx) || (vp[j].first <= ex && vp[j].second >= ex) || (sx <= vp[j].first && ex >= vp[j].second) || (sx >= vp[j].first && ex <= vp[j].second)){ 9 sx = max(sx, vp[j].first); 10 ex = min(ex, vp[j].second); 11 cnt++; 12 } 13 } 14 ans = max(ans, cnt); 15 }

質問

このアルゴリズムは計算量で言えば$0(N^2)$となっています。
そもそも、このアルゴリズムは正しいのでしょうか? (一応自分のテストケースをいくつか作ったものではうまくいっているのですが確信はありません)
正しい場合、もっと効率よくできたりしないでしょうか?

[追記]atcoderm leetcode, aojなどで関連問題があれば、教えて欲しいです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

まずそのコードの問題は

text

11 3 27 10 32 6 42 6 54 8 64 8

このような6つの区間が与えられたとき[4, 6]で4つの区間が重なりますが、そのアルゴリズムだと3が出ます。

最大重複数を求めるアルゴリズムであれば、区間の端点をソート(例として小さい順)して、順に区間の左端が来たら重複数に+1、右端が来たら-1としていくことでその地点での重複してる区間の数が出せます。(同じ地点に左端と右端が存在する場合の順序を変えることで閉区間と開区間どちらも対応できる)。
似た問題はあるはずですが、見つかりません。

投稿2020/06/17 14:00

yudedako67

総合スコア2047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問