IDS
This commit is contained in:
143
Algorithm/IterativeDeepening/Egypt-Fraction-AI.cpp
Normal file
143
Algorithm/IterativeDeepening/Egypt-Fraction-AI.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef long long ll; // ʹ<><CAB9> long long <20>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4>ķ<EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD>GCD<43><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
ll gcd(ll a, ll b) {
|
||||
return b == 0 ? a : gcd(b, a % b); // շת<D5B7><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> n/d Լ<><D4BC>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
||||
pair<ll, ll> reduce(ll n, ll d) {
|
||||
ll g = gcd(abs(n), d); // <20><><EFBFBD><EFBFBD> n <20><> d <20><> GCD<43><44>abs(n) <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
return {n / g, d / g}; // <20><><EFBFBD><EFBFBD>Լ<EFBFBD>ֺ<EFBFBD><D6BA>ķ<EFBFBD><C4B7>Ӻͷ<D3BA>ĸ
|
||||
}
|
||||
|
||||
// <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4>Ľṹ<C4BD><E1B9B9>
|
||||
struct State {
|
||||
ll num, den; // <20><>ǰʣ<C7B0><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> num/den
|
||||
vector<ll> dens; // <20><>ѡ<EFBFBD><D1A1><EFBFBD>ĵ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD>ĸ<EFBFBD>б<EFBFBD>
|
||||
|
||||
// <20><><EFBFBD>㵱ǰ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ
|
||||
ll max_den() const {
|
||||
if (dens.empty()) return 0; // <20><><EFBFBD><EFBFBD>û<EFBFBD>з<EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0
|
||||
return *max_element(dens.begin(), dens.end()); // <20><><EFBFBD>ط<EFBFBD>ĸ<EFBFBD>б<EFBFBD><D0B1>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||
}
|
||||
};
|
||||
|
||||
// <20><>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> unordered_set <20>д洢״̬<D7B4><CCAC><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>δʹ<CEB4>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD>չ<EFBFBD><D5B9>
|
||||
struct StateHash {
|
||||
size_t operator()(const State& s) const {
|
||||
string str;
|
||||
for (ll x : s.dens) str += to_string(x) + ",";
|
||||
str += to_string(s.num) + "/" + to_string(s.den);
|
||||
return hash<string>()(str);
|
||||
}
|
||||
};
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1>ǰ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD><D0BA><EFBFBD>״̬
|
||||
vector<State> get_successors(const State& state, int limit, int depth) {
|
||||
vector<State> res; // <20>洢<EFBFBD><E6B4A2><EFBFBD>п<EFBFBD><D0BF>ܵĺ<DCB5><C4BA><EFBFBD>״̬
|
||||
ll r = state.num, s = state.den; // <20><>ǰʣ<C7B0><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> r/s
|
||||
if (r == 0) return res; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ 0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ
|
||||
|
||||
// ȷ<><C8B7><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD>֤<EFBFBD><D6A4>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> r/s >= 1/d
|
||||
ll last_d = state.dens.empty() ? 0 : state.dens.back();
|
||||
ll min_d = max(last_d + 1, (s + r - 1) / r); // min_d = ceil(s/r)
|
||||
|
||||
// <20><><EFBFBD>÷<EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD>ޣ<EFBFBD><DEA3><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
const ll MAX_D = 10000000LL; // <20><><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>
|
||||
|
||||
// ö<>ٿ<EFBFBD><D9BF>ܵĵ<DCB5>λ<EFBFBD><CEBB>ĸ d
|
||||
for (ll d = min_d; d <= MAX_D; ++d) {
|
||||
// <20>Ż<EFBFBD><C5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>ಽ<EFBFBD><E0B2BD><EFBFBD>Ƿ<EFBFBD><C7B7>㹻<EFBFBD><E3B9BB>ʾʣ<CABE><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
int rem_steps = limit - depth - 1; // ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><C3B2><EFBFBD>
|
||||
double max_sum_after = 0.0; // ʣ<>ಽ<EFBFBD><E0B2BD><EFBFBD>ܱ<EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
for (int i = 1; i <= rem_steps; ++i) {
|
||||
max_sum_after += 1.0 / (d + i); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD>
|
||||
}
|
||||
double this_contrib = 1.0 / d; // <20><>ǰ<EFBFBD><C7B0>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><C4B9><EFBFBD>
|
||||
double target = (double)r / s; // Ŀ<><C4BF>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><D7BC>Ϻ<EFBFBD><CFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><DCB9><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>Ŀ<EFBFBD>꣬<EFBFBD><EAA3AC>֦
|
||||
if (this_contrib + max_sum_after < target - 1e-10) break;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD>r/s - 1/d = (r*d - s) / (s*d)
|
||||
ll new_num = r * d - s;
|
||||
if (new_num < 0) continue; // <20>·<EFBFBD><C2B7><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>״̬
|
||||
ll new_den = s * d;
|
||||
auto p = reduce(new_num, new_den); // Լ<><D4BC><EFBFBD>·<EFBFBD><C2B7><EFBFBD>
|
||||
State ns = {p.first, p.second, state.dens}; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
|
||||
ns.dens.push_back(d); // <20><><EFBFBD>ӵ<EFBFBD>ǰ<EFBFBD><C7B0>λ<EFBFBD><CEBB>ĸ
|
||||
res.push_back(ns); // <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DFS<46><53><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
void dfs(const State& state, int depth, int limit, vector<State>& solutions) {
|
||||
if (depth > limit) return; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (state.num == 0 && !state.dens.empty()) { // <20>ҵ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD>⣺<EFBFBD><E2A3BA><EFBFBD><EFBFBD>Ϊ 0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ĸ
|
||||
solutions.push_back(state); // <20><>¼<EFBFBD><C2BC>
|
||||
return; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>·<EFBFBD><C2B7>
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD><D0BA><EFBFBD>״̬
|
||||
for (const auto& next : get_successors(state, limit, depth)) {
|
||||
dfs(next, depth + 1, limit, solutions); // <20>ݹ<EFBFBD><DDB9><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IDS<44><53><EFBFBD><EFBFBD>Ѱ<EFBFBD><D1B0><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD><CCB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8>С<EFBFBD>İ<EFBFBD><C4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
State find_best_egyptian(ll a, ll b) {
|
||||
auto p = reduce(a, b); // Լ<><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
State start = {p.first, p.second, {}}; // <20><>ʼ״̬
|
||||
State best; // <20><>¼<EFBFBD><C2BC><EFBFBD>ѽ<EFBFBD>
|
||||
ll best_max = LLONG_MAX; // <20><><EFBFBD>ѽ<EFBFBD><D1BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ
|
||||
int limit = 0; // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
while (true) {
|
||||
++limit; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
vector<State> solutions; // <20>洢<EFBFBD><E6B4A2>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD>н<EFBFBD>
|
||||
dfs(start, 0, limit, solutions); // ִ<><D6B4> DFS
|
||||
if (!solutions.empty()) { // <20><><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD>
|
||||
for (const auto& s : solutions) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD>
|
||||
ll cur_max = s.max_den(); // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ
|
||||
if (cur_max < best_max) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѽ<EFBFBD>
|
||||
best = s;
|
||||
best_max = cur_max;
|
||||
}
|
||||
}
|
||||
return best; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѽ<EFBFBD>
|
||||
}
|
||||
if (limit > 100) { // <20><>ȫ<EFBFBD><C8AB><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
|
||||
cout << "No solution found within limit." << endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
ll a, b;
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӻͷ<D3BA>ĸ<EFBFBD><C4B8>Ҫ<EFBFBD><D2AA> 0 < a < b <20>һ<EFBFBD><D2BB><EFBFBD>
|
||||
cout << "Enter numerator and denominator (a b, with 0 < a < b, gcd=1): ";
|
||||
cin >> a >> b;
|
||||
if (a >= b || a <= 0 || gcd(a, b) != 1) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
||||
cout << "Invalid input: require 0 < a < b and gcd(a,b)=1" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
State result = find_best_egyptian(a, b); // Ѱ<><D1B0><EFBFBD><EFBFBD><EFBFBD>Ѱ<EFBFBD><D1B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
cout << a << "/" << b << " = ";
|
||||
for (size_t i = 0; i < result.dens.size(); ++i) {
|
||||
if (i > 0) cout << " + ";
|
||||
cout << "1/" << result.dens[i]; // <20><>ӡ<EFBFBD><D3A1>λ<EFBFBD><CEBB><EFBFBD><EFBFBD>
|
||||
}
|
||||
cout << endl;
|
||||
cout << "Length: " << result.dens.size() << endl; // <20><>ӡ<EFBFBD>ֽⳤ<D6BD><E2B3A4>
|
||||
cout << "Max denominator: " << result.max_den() << endl; // <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user