WolframHの回答に基づいて、サンプル入力の問題をC++で試してみましたが、うまくいくようです。また、サンプル入力で問題なく動作するphythonソリューションも試しました。興味深いのは、入力を少し大きな数 (つまり、3 と 18) に増やすと、C++とphythonの両方のソリューションが不確定な時間ハングすることです。
何がうまくいかなかったのですか?
偶然にも、昨日の夜、たまたま動的計画法のノートを読んでいて、加重独立集合問題について読んだところです。あはは!私たちは想定よりもはるかに多くの仕事をしています! の:
#include <math.h>
#include <iomanip>
#include <iostream>
using namespace std;
void get_tight_number(int base_max, int length)
{
double result = 0;
int _tight_numbers = 0;
double total = pow(base_max + 1, length);
for (int i = 0; i <= base_max; ++i)
{
_tight_numbers += get_tight_number_help(base_max, length, i);
}
result = 100 * _tight_numbers / total;
cout << fixed << setprecision(5) << result << "\n";
}
int get_tight_number_help(int base_max, int length, int endwith)
{
cout << "Length: " << length << "endwith: " << endwith << endl;
if (length < 1 || endwith < 0 || endwith > base_max)
return 0;
if (length == 1)
{
return 1;
} else
{
return get_tight_number_help(base_max, length - 1, endwith)
+ get_tight_number_help(base_max, length - 1, endwith + 1)
+ get_tight_number_help(base_max, length - 1, endwith - 1);
}
}
int main()
{
get_tight_number(8, 7);
return 0;
}
たくさんのprints
正しい結果があります0.10130
。これは、この入力に対して、ヘルパー関数が 7000 回以上呼び出されたことを意味しますgrep "endwith:" | wc -l
。7719
他の入力で何回呼び出されたかを把握するために、次のようにしました。
Input #
8, 8 22254
8, 6 2682
8, 5 933
あまり良くありません...再計算が多すぎます。bottom up
代わりに、参照配列のソリューションをまとめました。
int** tight_number_bottom_up(int base_max, int length)
{
int** result = new int*[base_max + 1];
for (int i = 0; i < base_max + 1; ++i)
{
result[i] = new int[length];
}
//Ends with i, i.e., looping over them
for (int j = 0; j < length + 1; ++j)
{
for (int i = 0; i < base_max + 1; ++i)
{
if (j == 0)
{
result[i][j] = 0;
} else if (j == 1)
{
result[i][j] = 1;
} else
{
int bigger = i == base_max ? 0 : result[i + 1][j - 1];
cout << "bigger: " << bigger << endl;
int smaller = i == 0 ? 0 : result[i - 1][j - 1];
cout << "smaller: " << smaller << endl;
result[i][j] = result[i][j - 1] + bigger + smaller;
}
}
}
return result;
}
ボトムアップ表を作成する際の反復回数は最大であると確信しており、(base_max + 1) * (length + 1)
書き終えたことに満足し、正しい結果が得られたことに満足しています。
フォローアップの質問(あなたがまだ私と一緒にいる場合)
double
9, 100
またはのような入力には十分ではないよう9, 50
ですが、「長い」ダブルを作成するにはどうすればよいですか?