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

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

新規登録して質問してみよう
ただいま回答率
85.49%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

2回答

1995閲覧

python3で[errror]list index out of rangeが解決できない

Sonono

総合スコア85

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2019/03/22 03:00

編集2019/03/22 03:04

atcoder Educational DP Contest B-Frog2をpython3で解いているのですが、

Traceback (most recent call last): File ".\atcoder.py", line 20, in <module> chmin(dp[i+j], dp[i]+abs(dp[i]-h[i+j])) IndexError: list index out of range

というエラーがでます。単純なミスだと思うのですが全くわからないまま時間が過ぎてしまったのでどなたか教えていただけると幸いです。コードは以下になります。Qiitaの解説を参考にしています。

import math import sys import os f = open('input.txt', 'r') sys.stdin = f def chmin(a, b): if a > b: a = b return a n, k = map(int, (input().split())) h = list(input().split()) h = [int(i) for i in h] dp = [100000]*n dp[0] = 0 for i in range(0, n): for j in range(1, k+1): if i+j <= n: chmin(dp[i+j], dp[i]+abs(dp[i]-h[i+j])) print(dp[n-1])

input

15 3 210 30 40 50 20 3

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

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

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

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

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

guest

回答2

0

ご質問の件は、tachikomaさんが回答済なので別件についてです。

chmin()関数でdp[]の内容を更新したいのだと思いますが、この関数に渡されているa, bはdp[]そのものではなく値のコピーです。なので、a = b と書いてもdp[]の内容を変更することはできません。dp[]を直接更新するようなコードを書く必要があります。

chmin()に渡すbを計算する部分ですが、ここで必要なのは
i番目の足場までのコスト + (i番目の足場からi+j番目の足場に移るためのコスト) なので
dp[i] + abs(dp[i] - h[i+j]) ではなく dp[i] + abs(h[i] - h[i+j]) だと思います。

dpのリストを 100000 で初期化していますが、以下のようにK=1で足場がデコボコで正しい答えが100000を越えるケースでは正しく計算できなくなります。float('inf')とか10**10など、もっと大きな値で初期化する必要があると思います。

text

1100000 1 21 10000 1 10000 1 10000, 1, ...

1-3を反映させたコードは以下の通りです。

python

1 2def chmin(i, j): 3 a, b = dp[i+j], dp[i]+abs(h[i]-h[i+j]) 4 if a > b: 5 dp[i+j] = b 6 7 8n, k = map(int, (input().split())) 9h = list(input().split()) 10h = [int(i) for i in h] 11dp = [10**10]*n 12dp[0] = 0 13for i in range(0, n): 14 for j in range(1, k+1): 15 if i+j < n: 16 chmin(i, j) 17print(dp[n-1])

ただし、上記のコードをPython3 (3.4.3)で提出すると制限時間オーバー(TLE)になります。
chminを別関数にせずにfor jループ内に埋め込むなど、処理時間を速くするための工夫が必要です。
(もしくは、提出言語としてPyPy3を選択するとACになるかもしれません)

投稿2019/03/22 04:45

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Sonono

2019/03/22 06:17

丁寧にありがとうございます。なんか反映されないなと思って関数をやめたところでした。。。なぜかpythonだとINFないと思い込んでいたので助かりました!ありがとうございます。ご存知でしたら教えていただきたいのですが、質問本文「Qiitaの解説」のリンク先では、c++ですが上のようなchmin()関数で動いています。c++では引数そのものを関数で扱える(変更できる)が、pythonでは値のコピーになってしまうということでしょうか。
退会済みユーザー

退会済みユーザー

2019/03/22 09:00

とりあえずは「pythonでは配列(リスト)の要素を関数に渡しても、呼び出した先の関数で元々の配列を変更することはできない」と覚えておけば良いと思います。←この説明は厳密には正しくないので、気になるようであればpythonの本を読んでみるか「python 参照渡し リスト」あたりのキーワードで検索してみてください。
guest

0

ベストアンサー

i+j <= ni+j < nじゃないとまずそうですね。Pythonのインデックスは0-baseなので、長さnのリスト等に対して有効なインデックスは[0, n-1]なんです。

投稿2019/03/22 03:14

tachikoma

総合スコア3601

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

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

Sonono

2019/03/22 06:10

ありがとうございます!エラー解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問