สมมติว่าเรามีตัวเลข n ทีนี้ลองพิจารณาการดำเนินการที่เราสามารถทำได้ 1. ลดค่า n ลงหนึ่ง 2. ถ้า n เป็นจำนวนคู่ ให้ลดค่าลงโดย n / 2 3. ถ้า n หารด้วย 3 ลงตัว ให้ลดลง 2 * (n / 3) ในที่สุดก็หา จำนวนการดำเนินการขั้นต่ำที่จำเป็นในการลด n เป็นศูนย์
ดังนั้น หากอินพุตเป็น n =16 ผลลัพธ์จะเป็น 5 เนื่องจาก n =16 แม้จะลดลง n/2 4 เท่า มันจะเป็น 1 จากนั้นลด 1 เพื่อให้ได้ 0 ดังนั้นรวม 5 การดำเนินงาน
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดหนึ่งแผนที่ dp
-
กำหนดฟังก์ชัน dfs() ซึ่งจะใช้เวลา x
-
ถอยหลัง :=x
-
ถ้า x เป็น dp แล้ว −
-
กลับ dp[x]
-
-
ถ้า x <=0 แล้ว −
-
ผลตอบแทน x
-
-
ถ้า x เท่ากับ 1 แล้ว −
-
กลับ 1
-
-
md2 :=x mod 2
-
md3 :=x mod 3
-
ret :=ขั้นต่ำของ {ret, md2 + 1 + dfs((x - md2) / 2), md3 + 1 + dfs((x - md3) / 3)}
-
ผลตอบแทน dp[x] =ret
-
จากการเรียกเมธอดหลักและส่งคืน dfs(n)
ตัวอย่าง
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
#include <bits/stdc++.h>
using namespace std;
unordered_map <int, int> dp;
int dfs(int x){
int ret = x;
if(dp.count(x))
return dp[x];
if(x <= 0)
return x;
if(x == 1)
return 1;
int md2 = x % 2;
int md3 = x % 3;
ret = min({ret, md2 + 1 + dfs((x - md2) / 2), md3 + 1 + dfs((x - md3) / 3)});
return dp[x] = ret;
}
int solve(int n) {
return dfs(n);
}
int main(){
int n = 16;
cout << solve(n);
} อินพุต
16
ผลลัพธ์
5