- ベストアンサー
AOJの問題で質問あります
- AOJの問題で考えても全然わからない問題があり、他の人の解答例を参考にしようと思い、見てみたのですが、一つ分からないところがあり、質問させていただきます。
- 問題URL:[http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0089](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0089) 自分が参考にしている解答例のURL:[http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=570672](http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=570672)
- 質問内容:「solve」関数の役割や値の返り値が分からないです。解答例では計算結果が`data[cnt-1][0]`に格納されていますが、詳細が分かりません。また、`solve`関数内の処理の詳細や端のみを足している`data`の役割も教えていただきたいです。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
コメントがまったく無いので、わかりずらいプログラムになってしまっています。 「何をしているか?」を考えてコメントを付けてみてはどうでしょうか。 > //ここでは、計算した結果、どのような値が帰ってくるのでしょうか? voidですから、戻り値はありませんが、第一引数で指定した配列が変更されます。 どうしてそうなるか理解できない場合は、参考書等でポインタの勉強してください > printf("%d\n",data[cnt-1][0]); 結果らしきものを出力している箇所はここだけです。 ということは ・data[cnt-1][0] が結果ではないだろうか? と予想できます。すると ・配列 data には、もともと入力したデータが入っていたはず ・入力から出力までの間に solve関数を実行している ということから、solve関数で配列dataが書き変わっているのでは?と予想できます。 ○solve関数の動作 実際に、コンピュータになったつもりで、動作を追い掛けてはですか? ・i=0 のとき、 data[0] : a0 data[1] : b0 b1 data[2] : c0 c1 c2 data[i+1][0] += data[i][0]; → data[1][0] += data[0][0] ; → data[1][0] +=a0 data[i+1][i+1] += data[i][i]; → data[1][1] += data[0][0] ; → data[1][1] +=a0 j=1 は j<=iではないので、forループは実行されず 結果 data[0] : a0 data[1] : b0+a0 b1+a0 data[2] : c0 c1 c2 ・i=1のとき data[i+1][0] += data[i][0]; → data[2][0] += data[1][0] ; → data[2][0] +=b0+a0 data[i+1][i+1] += data[i][i]; → data[2][2] += data[1][1] ; → data[2][2] +=b1+a0 j=1 data[i+1][j] += max(data[i][j-1],data[i][j]); →data[2][1] += max(data[1][0],data[1][1]); →data[2][1] += max(b0+a0,b1+a0); 結果 data[0] : a0 data[1] : b0+a0 b1+a0 data[2] : c0+b0+a0 c1+max(b0+a0,b1+a0) c2+b1+a0 ここまで追い掛けたら、solveがどんな方法で結果をだそうとしているのか、わかるのではないでしょうか? 幅が広がっていく部分では、候補は1つしかありません。 あえてやるなら次のようになります。 for(j = 0;j <= i+1;j++) として ・data[i+1][0] += max(data[i][-1],data[i][0]); // ただし、範囲外となる data[i][-1]は0とする ・data[i+1][i+1] += max(data[i][i],data[i][i+1]); // ただし、範囲外となる data[i][i+1]は0とする data[i][i+1]の方は、サイズを大きく取って、予め0にしておく、という方法で対応できます。 しかし、data[i][-1]は先に添字をチェックする必要があります。 それなら、候補が1つしか無い場合は、そのまま計算した方がいいのではないでしょうか。
お礼
なるほど! 具体的に書いてみると、この関数の動きが分かりますね! やっと理解できました。ありがとうございます。 あと、ご指摘の通り、回答者様に理解されやすいような説明、書き方をしていくことを念頭に置き、今後はやっていこうと思います。