ภาพรวมปัญหา
กำหนดจำนวนเต็มบวก n หาจำนวนจำนวนเต็มไม่ติดลบ ≤ n ที่ตัวแทนไบนารีไม่มี 1 ติดกัน ตัวอย่าง: n=7 → คำตอบ 5 (0,1,2,4,5 = 0,1,10,100,101)
แนวทางแก้ปัญหา (Fibonacci + Bit DP)
- แปลง n เป็นสตริงบิต (LSB first)
- ones[i], zeroes[i] = จำนวนสตริงบิตความยาว i+1 ที่ลงท้ายด้วย 1, 0 ตามลำดับ ไม่มี 11
- zeroes[i] = zeroes[i-1] + ones[i-1], ones[i] = zeroes[i-1] (Fibonacci)
- รวม zeroes[n-1] + ones[n-1] แล้วลบกรณีที่เกิน n โดยดูบิตของ n
ตัวอย่างโปรแกรม
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
string convert(int n) {
string ret = "";
while(n) {
ret += (n % 2) + '0';
n >>= 1;
}
return ret;
}
int findIntegers(int num) {
string bits = convert(num);
int n = bits.size();
vector<int> ones(n), zeroes(n);
ones[0] = zeroes[0] = 1;
for(int i = 1; i < n; i++) {
zeroes[i] = zeroes[i - 1] + ones[i - 1];
ones[i] = zeroes[i - 1];
}
int ret = ones[n - 1] + zeroes[n - 1];
for(int i = n - 2; i >= 0; i--) {
if(bits[i] == '0' && bits[i + 1] == '0') ret -= ones[i];
else if(bits[i] == '1' && bits[i + 1] == '1') break;
}
return ret;
}
};
int main() {
Solution ob;
cout << (ob.findIntegers(7));
}
Input
7
Output
5