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

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

新規登録して質問してみよう
ただいま回答率
85.48%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

C++

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

735閲覧

Pyhtonで動的計画法を書きました

fu_3823

総合スコア81

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

C++

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/07/10 08:42

動的計画法の勉強過程で、c++で書かれたコードを参考にpythonを使って書いてみました。
しかし、同じような結果になりません。
配列の使い方が少し違いますが、同じような動きをするはずと思って書いたのですが、うまくいかず、間違っているところもわかりません。pythonのコードのどこが間違っているのでしょうか?

以下、問題はAtcoderのサイトからの転記です。


問題文
N段の階段があります。高橋君は現在、上り口(0段目)にいます。 高橋君は一歩で 1段か2段上ることができます。
ただし、a1,a2,a3,....aM段目の床は壊れており、その段に足を踏み入れることは危険です。
壊れている床を踏まないようにしながら、最上段(N段目)にたどりつくまでの移動方法は何通りあるでしょうか? 総数を
1,000,000,007で割った余りを求めてください。

制約
1≦N≦10^5
0≦M≦N−1
1≦a1<a2<...<aM≦N−1

入力例
6 1
3
出力例
4


C++

1//正解 2#include <iostream> 3#include <vector> 4using namespace std; 5const int MOD = 1000000007; 6 7int N, M; 8vector<bool> issafe; 9 10int main() { 11 cin >> N >> M; 12 issafe.assign(N+1, true); 13 for (int i = 0; i < M; ++i) { 14 int a; cin >> a; 15 issafe[a] = false; 16 } 17 18 vector<int> dp(N+1, 0); 19 20 dp[0] = 1; 21 if (issafe[1]) dp[1] = 1; 22 23 for (int n = 2; n <= N; ++n) { 24 if (issafe[n-1]) dp[n] += dp[n-1]; 25 if (issafe[n-2]) dp[n] += dp[n-2]; 26 dp[n] %= MOD; 27 } 28 cout << dp[N] << endl; 29}

Pyhton

1###以下がうまくいかないコードです。 2n, m = map(int, input().split()) 3a = [] 4[a.append(int(input())) for _ in range(m)] 5 6dp = [0] * 10000 7dp[0] = 0 8if 1 not in a: 9 dp[1] = 1 10 11for i in range(2, n + 1): 12 if (i - 1) not in a: 13 dp[i] = dp[i] + dp[i - 1] 14 if (i - 2) not in a: 15 dp[i] = dp[i - 2] + dp[i] 16 17 dp[i] %= 1000000007 18 19print(dp[n])

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

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

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

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

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

kairi003

2020/07/10 12:10 編集

全然本筋と関係無いことで申し訳ないのですが、すごく気になったので… 可読性も速度的にも、包括表記するなら a = [int(input()) for _ in range(m)] でいいと思います
fu_3823

2020/07/11 01:19 編集

計算量のことと合わせて、参考になります。 ありがとうございました。
guest

回答2

0

ベストアンサー

kazatsuyuさんのに加えて、listは内部的に配列ですので、inで値の存在を確かめるには先頭から順に中身を見ていくことになります。

つまり計算量はO(N)であり、さらにこれをforループしてるのでO(N^2)になって制約的にでかいのがくると確実に間に合いません。

存在確認が平均計算量O(1)であるset型(集合型)を使いましょう。

キーだけの辞書みたいな感じで定義できるので包括表記するとこんな感じです↓

Python

1a = {input() for _ in range(m)}

投稿2020/07/10 12:25

編集2020/07/10 12:35
kairi003

総合スコア1330

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

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

fu_3823

2020/07/11 01:20

計算量について質問させてください。 セット内包表記で書きましたが、一部の入力がTLEでなくREになりました。これはやはり計算量の問題でしょうか。推測しかできないと思いますが、分かるようでしたら教えていただきたいです。
kairi003

2020/07/11 07:20 編集

REは普通にエラーですね。 dpの長さが10000になってますがN+1は最大100001なのでNがでかいとforループでリストの範囲外を参照してlist index out of rangeします。 c++のようにN+1にするか100010くらいにしておけばいいと思います。
fu_3823

2020/07/12 02:31

ありがとうございます。とても参考になりました。
guest

0

cpp

1dp[0] = 1;

python

1dp[0] = 0

ここじゃないでしょうか

投稿2020/07/10 09:12

kazatsuyu

総合スコア158

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

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

fu_3823

2020/07/11 00:16

あ。 ・・・。 ありがとうございます。 自分では発見できませんでした。 たぶん、時間をかけても気漬けづけなかったと思うので、助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問