Red Huang

Red Huang

お金の両替問題

お金の両替問題の各種延伸問題

 

特定の価格を作ることができるか(お金の両替問題)

  1. int price [5] = {5, 2, 6, 11, 17};   // 各種面額、順序は自由。

  2. bool c[1000+1];

  3. // {5, 2, 6, 11, 17} の面額で価格 m を作れるか確認する

  4. void change(int m)

  5. {

  6.     memset(c, false, sizeof(c));

  7.     c[0] = true;

  8.     for (int i = 0; i < 5; ++i)             // 各種面額を順に追加

  9.         for (int j = price [i]; j <= m; ++j) // 低価格から高価格へ

  10.             c [j] ||= c [j-price [i]];         // 作れる、作れる、作れる

  11.     if (c[m])

  12.         cout << "作れる";

  13.     else

  14.         cout << "作れない";

  15. }

  16. int price[5] = {5, 2, 6, 11, 17};

  17. int c [5][1000+1];   // 0 以上は計算済み、-1 は未計算。

  18.                     // 最初はすべて - 1 で初期化する必要がある。

  19. void change(int n, int m)

  20. {

  21.     if (n < 0 || m < 0) return 0;   // 0 は false を意味する

  22.     if (m == 0) return 1;           // 1 は true を意味する

  23.     if (c[n][m] != -1) return c[n][m];

  24.     return c[n][m] = change(n-1, m) | change(n, m - price[n]);

  25. }

特定の価格を作る方法は何通りか(コイン変更問題)

  1. int price[5] = {5, 2, 6, 11, 17};

  2. int c[1000+1];

  3. void change(int m)

  4. {

  5.     memset(c, 0, sizeof(c));

  6.     c[0] = 1;

  7.     for (int i = 0; i < 5; ++i)

  8.         for (int j = price[i]; j <= m; ++j)

  9.             c[j] += c[j-price[i]];

  10.     cout << "価格" << m << "を作る方法は" << c [m] << "通り";

  11. }

特定の価格を作るための最小コイン数(コイン作成問題)

  1. int price[5] = {5, 2, 6, 11, 17};

  2. int c[1000+1];

  3. void change(int m)

  4. {

  5.     memset(c, 0x7f, sizeof(c));

  6.     c[0] = 0;

  7.     for (int i = 0; i < 5; ++i)

  8.         for (int j = price[i]; j <= m; ++j)

  9.             c[j] = min(c[j], c[j-price[i]] + 1);

  10.     cout << "価格" << m;

  11.     cout << "最小で(のみ)" << c [m] << "枚のコインが必要";

  12. }

特定の価格を作るためのコインの使用量、どのような可能性があるか。

  1. int price[5] = {5, 2, 6, 11, 17};

  2. long long c [1000];  // 各セルは 1 つのビットセット、

  3.                     // その価格を作るために使用できるコインの数を記録し、さまざまな可能性を含む。

  4. void change(int m)

  5. {

  6.     memset(c, 0, sizeof(c));

  7.     c[0] = 1;

  8.     for (int i = 0; i < 5; ++i)

  9.         for (int j = price[i]; j <= m; ++j)

  10.             // コインの数を 1 増やし、各可能性を 1 増やす。

  11.             c[j] |= c[j-price[i]] << 1;

  12.     for (int i = 1; i <= 63; ++i)

  13.         if (c[m] & (1 << i))

  14.             cout << "コイン" << i << "枚で価格" << m "を作ることができる";

  15. }

特定の価格を作ることができるか、ただしコインの供給に制限がある。

  1. int price[5] = {5, 2, 6, 11, 17};

  2. int num [5] = {4, 5, 5, 3, 2};   // 各種面額の供給量

  3. bool c[1000+1];

  4. void change(int m)

  5. {

  6.     memset(c, 0, sizeof(c));

  7.     c[0] = true;

  8.     for (int i = 0; i < 5; ++i)

  9.         for (int k = 0; k < M [i]; ++k)  // 各種余数を分けて処理

  10. //      for (int k = 1; k <= M [i]; ++k) // 少し早い書き方

  11.         {

  12.             int left = T[i];

  13.             for (int j = k; j <= m; j += M [i])  // 低価格から高価格へ

  14.                 // 0 種類から i 種類の面額で作れる場合、コインを節約できる。

  15.                 if (c[j])

  16.                 {

  17.                     left = T [i];    // 弾薬を補充

  18.                 }

  19.                 // 過去に作れなかった場合、現在の面額を使って作る必要がある。

  20.                 else if (left > 0)

  21.                 {

  22.                     left--; // コインを 1 枚使用

  23.                     c[j] = true;

  24.                 }

  25.         }

  26.     if (c[m])

  27.         cout << "作れる";

  28.     else

  29.         cout << "作れない";

  30. }

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。