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

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

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

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

C++

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

Q&A

解決済

1回答

426閲覧

部分和問題 / 真偽値か場合の数を扱うかで答えが変わってしまう

kay_ventris4

総合スコア269

アルゴリズム

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

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

C++

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

0グッド

0クリップ

投稿2022/08/01 02:52

編集2022/08/01 02:56

問題

AtCoder Beginner Contest 204 D問題

方針

配列の値を集合1と集合2に分け、各総和の差が最小となるような時の、両集合の最大値を求める。

正解コード

こちらは、dp[i][j] := 「i番目までの要素を見た時に、総和をjとすることは可能か?」というdpテーブルを作ることで実装しました。

C++

1#include <bits/stdc++.h> 2#include <math.h> 3using namespace std; 4#define ll long long 5 6/* import vector from standard input */ 7vector<ll> import_vector(ll n) { vector<ll> li = {}; for (ll i = 0; i < n; i++) { ll j; cin >> j; li.push_back(j); } return li; } 8 9/* max(a, b) */ 10ll larger(ll a, ll b) { if (a >= b) { return a; } else { return b; } } 11 12/* sum */ 13ll total(vector<ll> li) { ll ans = 0; for (ll i = 0; i < li.size(); i++) { ans += li.at(i); } return ans; } 14 15void solve() { 16 ll N; cin >> N; 17 vector<ll> A = import_vector(N); 18 19 vector<vector<bool>> dp = {}; 20 for (ll i = 0; i < N; i++) { 21 vector<bool> cand = {}; 22 for (ll j = 0; j <= total(A); j++) { 23 cand.push_back(false); 24 } 25 dp.push_back(cand); 26 } 27 28 dp.at(0).at(A.at(0)) = true; 29 for (ll i = 0; i < N; i++) { 30 dp.at(i).at(0) = true; 31 } 32 33 for (ll i = 1; i < N; i++) { 34 for (ll j = 0; j <= total(A); j++) { 35 if (j >= A.at(i)) { 36 dp.at(i).at(j) = (dp.at(i - 1).at(j - A.at(i)) || dp.at(i - 1).at(j)); 37 } 38 else { 39 dp.at(i).at(j) = dp.at(i - 1).at(j); 40 } 41 } 42 } 43 44 vector<bool> check = dp.at(N - 1); 45 ll faster = 0; 46 for (ll j = 0; j <= total(A); j++) { 47 if (2 * j <= total(A) && check.at(j)) { 48 faster = j; 49 } 50 } 51 52 ll slower = total(A) - faster; 53 cout << larger(slower, faster) << endl; 54} 55 56int main() { 57 solve(); 58}

不正解コード

方針は全く同じですが、dp[i][j] := 「i番目までの要素を見た時に、総和をjとする選び方の場合の数は何通りか?」というdpテーブルを組みました。

C++

1#include <bits/stdc++.h> 2#include <math.h> 3using namespace std; 4#define ll long long 5 6/* import vector from standard input */ 7vector<ll> import_vector(ll n) { vector<ll> li = {}; for (ll i = 0; i < n; i++) { ll j; cin >> j; li.push_back(j); } return li; } 8 9/* max(a, b) */ 10ll larger(ll a, ll b) { if (a >= b) { return a; } else { return b; } } 11 12/* sum */ 13ll total(vector<ll> li) { ll ans = 0; for (ll i = 0; i < li.size(); i++) { ans += li.at(i); } return ans; } 14 15void solve() { 16 17 ll N; cin >> N; 18 vector<ll> A = import_vector(N); 19 20 vector<vector<ll>> dp = {}; 21 for (ll i = 0; i < N; i++) { 22 vector<ll> cand = {}; 23 for (ll j = 0; j <= total(A); j++) { 24 cand.push_back(0); 25 } 26 dp.push_back(cand); 27 } 28 29 dp.at(0).at(A.at(0)) = 1; 30 for (ll i = 0; i < N; i++) { 31 dp.at(i).at(0) = 1; 32 } 33 34 for (ll i = 1; i < N; i++) { 35 for (ll j = 0; j <= total(A); j++) { 36 if (j >= A.at(i)) { 37 dp.at(i).at(j) = dp.at(i - 1).at(j - A.at(i)) + dp.at(i - 1).at(j); 38 } 39 else { 40 dp.at(i).at(j) = dp.at(i - 1).at(j); 41 } 42 } 43 } 44 45 vector<ll> check = dp.at(N - 1); 46 ll faster = 0; 47 for (ll j = 0; j <= total(A); j++) { 48 if (2 * j <= total(A) && check.at(j) > 0) { 49 faster = j; 50 } 51 } 52 53 ll slower = total(A) - faster; 54 cout << larger(slower, faster) << endl; 55} 56 57int main() { 58 solve(); 59}

質問

両者は基本的には全く同一のアルゴリズムで組み立てられていて、違いといえば「可能か?」の部分を「何通りか?」に変えただけで、これは後者の値が0より大きい時前者の可能であるということに対応すると考えておりました。しかし、ジャッジでは複数個のテストケースにおいて不正解が出る結果となりました。一体どの部分が起因してこのようになってしまうのでしょうか。素人質問にて恐縮ですが、ご教授のほど何卒よろしくお願い申し上げます。

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

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

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

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

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

guest

回答1

0

自己解決

99
1000 ... 1000
のようなケースが不正解を出していましたが、よくよく調べると多数の箇所でオーバーフローを起こしていました。こういった場合場合の数が巨大になり得るということを想定しきれていませんでした。

投稿2022/08/01 05:58

kay_ventris4

総合スコア269

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問