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

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

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

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

C++

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

Q&A

解決済

1回答

874閲覧

AtCoderアルゴリズムと数学演習問題集

TANAKA

総合スコア3

アルゴリズム

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

C++

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

0グッド

0クリップ

投稿2022/08/11 10:22

AtCoderアルゴリズムと数学演習問題集の009 ”Brute Force 2” を解いています。
009 - Brute Force 2

どこが間違っているのか分かりません。
自分のコードのどこが間違っているか指摘してほしいです。
お願いします。

自分のこれです。

c++

1#include<iostream> 2#include<vector> 3using namespace std; 4 5template<class T>void ch(T& a, T b) { 6 if (a < b)a = b; 7} 8int main() { 9 int i, j; 10 long long n, w; 11 cin >> n >> w; 12 vector<long long>a(n + 1); 13 vector<vector<long long>>dp(n + 5, vector<long long>(w + 5, 0)); 14 for (i = 1; i <= n; i++)cin >> a[i]; 15 for (i = 1; i <= n; i++) { 16 for (j = 0; j <= w; j++) { 17 dp[i][j] = dp[i - 1][j]; 18 if (j - a[i] >= 0) { 19 dp[i][j] = a[i]; 20 ch(dp[i][j], (dp[i][j] += dp[i - 1][j - a[i]])); 21 22 } 23 } 24 } 25 for (i = 1; i <= n; i++) { 26 for (j = 0; j <= w; j++) { 27 cout << dp[i][j]; 28 } 29 cout << endl; 30 } 31 if (dp[n][w] == w)cout << "Yes" << endl; 32 else cout << "No" << endl; 33}

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

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

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

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

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

guest

回答1

0

ベストアンサー

ch(dp[i][j], (dp[i][j] += dp[i - 1][j - a[i]]));
これだと、+= により、関数ch の呼出しの前に dp[i][j] の値が変更されます。
関数ch の中の a は dp[i][j] であり、b は dp[i][j] の値です。
したがって、a の値と b の値は常に等しく、a < b は true になりません。
関数 ch は何もしないことになります。
dp[i][j] + dp[i - 1][j - a[i]] が dp[i][j] より小さいときは
dp[i][j] を変更してはいけないのに、その小さい値に変更されてしまいます。

+=+ に変えてみてください。

追記

C++

1 if (j - a[i] >= 0) { 2 ch(dp[i][j], a[i] + dp[i - 1][j - a[i]]); 3 }

このように変更するとどうなりますか?

どのような入力についてダメな結果になるのですか?

投稿2022/08/13 22:44

編集2022/08/14 23:53
kazuma-s

総合スコア8224

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

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

TANAKA

2022/08/14 01:51

回答ありがとうございます。+に変えてみたのですが元のコードと同じ結果になりました。ありえないことがおきているので、僕のコードがぶち壊れているのだと思います。この回答を参考にしてもう一回組みなおしてみます。
kazuma-s

2022/08/14 10:10

元のコードと同じ結果になったというのは、どのような入力についてどのような結果になったのですか?
TANAKA

2022/08/15 00:53

3 11 4 11 2 5 9 3 1 4 5 Yes No こうなりました。元コードの+=を+に変えても結果は変わりませんでした。
kazuma-s

2022/08/15 12:32 編集

なぜ、2つの例をひとつにまとめて書くんですか? しかもこれは AtCoder の問題にある例で出力の yes no は間違っていませんよね。 結果が間違う例を挙げてくださいと言っているのです。 回答に追記したように += を + にするだけではダメで、 a[i] + dp[i-1][j-a[i]] にしないといけません。
TANAKA

2022/08/15 12:32

すいませんこれですね。 5 16 3 4 5 4 1 と入力するとNo(本当はYes)がでます。追記に書いてくださったコードに変えてみてもNoでした。
kazuma-s

2022/08/15 12:39

追記のコードで 5 16 3 4 5 4 1 0 0 0 3 3 3 3 3 3 3 3 3 3 3 3 3 3 0 0 0 3 4 4 4 7 7 7 7 7 7 7 7 7 7 0 0 0 3 4 5 5 7 8 9 9 9 12 12 12 12 12 0 0 0 3 4 5 5 7 8 9 9 11 12 13 13 13 16 0 1 1 3 4 5 6 7 8 9 10 11 12 13 14 14 16 Yes となりました。 質問のコードの dp[i][j] = a[i]; は削除しましたか?
TANAKA

2022/08/16 09:40

dp[i][j] = a[i]をなくしたらできました。dp[i][j] = a[i]によって一列前の数字をかき消してしまっていたのですね。ありがとうございます。 自分の考えが至らないため、ここまでつきあわせてしまいました。本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問