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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

659閲覧

dpを用いた組み合わせの計算

grape_ll

総合スコア83

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/05/16 11:42

コード

html

1import java.util.Scanner; 2public class TypicalStairs { 3 public static void main(String[] args){ 4 Scanner scan=new Scanner(System.in); 5 int N=scan.nextInt(); 6 int M=scan.nextInt(); 7 int[] a=new int[M]; 8 for(int i=0;i<M;i++){ 9 a[i]=scan.nextInt(); 10 if(i!=0){ 11 if(a[i]-a[i-1]==1){ 12 System.out.println(0); 13 return ; 14 } 15 } 16 } 17 long[] dp=new long[N+1]; 18 dp[0]=1; 19 int j=0; 20 for(int i=0;i<N;i++){ 21 if((i+1)!=a[j]){ 22 if(i==0) dp[i+1]=dp[i]; 23 else dp[i+1]=dp[i]+dp[i-1]; 24 j++; 25 } 26 else dp[i+1]=0; 27 } 28 System.out.println(dp[N]%1000000007); 29 } 30}

#入力とエラーメッセージ
6 1
3
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at TypicalStairs.main(TypicalStairs.java:21)

#質問内容
エラーメッセージを見ると配列にいれられていないということだと思うのですが,なぜこうなってしまうのか教えていただきたいです。
入力の場所は21行目ではないのにここでこうなってしまう理由が全く分からないです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

java

1int M=scan.nextInt();

で a[] の要素数が決まるわけですが、 示された入力値だと 1 になります。この場合、a[] の最大インデックスは 0 になります。

java

1 for(int i=0;i<N;i++){ 2 if((i+1)!=a[j]){ 3 if(i==0) dp[i+1]=dp[i]; 4 else dp[i+1]=dp[i]+dp[i-1]; 5 j++; 6 } 7 else dp[i+1]=0; 8 }

で a[] の要素数に関係なく j が増えていき、この例ですと (i+1)!=a[1] で a[1] にアクセスしようとして、ArrayIndexOutOfBoundsException が発生しています。

【最後の入力パターンの出力結果が異なった理由】

i+1==a[j] の時が、i+1段目が壊れた床の時なので (i+1)!=a[j]j++ してしまうと壊れた床でなくても次の壊れた床の段を取得してしまいます。

なので正しくは、else ブロックで j++ する必要があります。

java

1 dp[0]=1; 2 int j=0; 3 for(int i=0;i<N;i++){ 4 if((i+1)!=a[j]){ 5 if(i==0) dp[i+1]=dp[i]; 6 else dp[i+1]=dp[i]+dp[i-1]; 7 } 8 else { 9 dp[i+1]=0; 10 if (j < M-1) j++; 11 } 12 }

なお、こうした場合、スキャン時の壊れた段が続く場合を考慮に入れなくても大丈夫です。

java

1 for(int i=0;i<M;i++){ 2 a[i]=scan.nextInt(); 3// if(i!=0){ 4// if(a[i]-a[i-1]==1){ 5// System.out.println(0); 6// return ; 7// } 8// } 9 }

例えば、4段目・5段目と壊れた床が続いていた場合、dp[4]dp[5] はともに 0 になるため、以降、dp[i]+dp[i-1]; の結果が常に 0 となるためです。

 なお、N が 10 の 5 乗まで許されることから、dp[i+1] の計算が終わった時点で 1000000007 を超えたら、1000000007 を引く処置をしておいた方が良いかもしれません。

java

1 dp[0]=1; 2 int j=0; 3 for(int i=0;i<N;i++){ 4 if((i+1)!=a[j]){ 5 if(i==0) dp[i+1]=dp[i]; 6 else dp[i+1]=dp[i]+dp[i-1]; 7 if(dp[i+1] >= MOD) dp[i+1] -= 1000000007; 8 } 9 else { 10 dp[i+1]=0; 11 if (j < M-1) j++; 12 } 13 }

参考: 「1000000007 で割ったあまり」の求め方を総特集! 〜 逆元から離散対数まで 〜 - Qiita

投稿2020/05/16 12:09

編集2020/05/18 14:46
Yasumichi

総合スコア1773

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

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

grape_ll

2020/05/16 12:33

a[1]にアクセスしたりするのを防ぐために if(j<M-1) j++; としたら ArrayIndexOutOfBoundsException は現れなくなりました。 ありがとうございます。 しかし,直したものを提出してみたらAC,RE,WAが入り混じった結果となっていたので どこが怪しいかを教えていただけると幸いです。 問題は以下のようになっています。 https://atcoder.jp/contests/abc129/tasks/abc129_c よろしくお願いいたします。
Yasumichi

2020/05/16 13:20

# AtCoder 使っていない人には、AC,RE,WA とか言われても分からないですよ。(用語集見たので理解はしましたが。) 逆に質問してみます。dp[i] に入る値の意味は、どういう意味と想定していますか?(一応、予想してはいますが。)
grape_ll

2020/05/17 05:59

申し訳ございません。配慮が不足しておりました。 わざわざ調べていただきありがとうございます。 私の考えとしては、段数iにたどり着く経路の数を表していると想定していますが、この考えはあっていますでしょうか。 よろしくお願いします。
Yasumichi

2020/05/18 14:49

最後の入力パターン 100 5 1 23 45 67 89 の出力結果が、608200469 ではなく 516971670 と誤った結果になった原因が分かりましたので追記しました。原因は、j++ していた場所でした。
grape_ll

2020/05/19 10:31

理解することが出来ました!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問