POJ 3252 Round Numbers
题目大意:
求[a,b]内转换成二进制之后0的个数大于等于1的个数的数的数量。
题解:
设dp[i][j]表示当前为第i位,0的个数与1的个数的差值为j的数的数量,因为差值可能为负,所以让它整体加32防止出现负数。
之后就是数位dp和记忆化搜索,参数中num表示0和1的个数差,pre表示高位是否出现过1,只有高位出现过1,此时的0才能计数。
#include <iostream>
#include <cstring>
using namespace std;
int dp[35][70], digit[70];
int dfs(int pos, int num, bool pre, bool limit) {
// num:0和1的个数差,由于要记忆化搜索,所以整体加32防止出现负数
// pre:高位是否有1出现过
if (pos <= 0) return num >= 32;
if (pre && !limit && dp[pos][num] != -1) return dp[pos][num]; // 没限制则用记忆化搜索
int up = limit ? digit[pos] : 1;
int ans = 0;
for (int i = 0; i <= up; ++i) {
if (!pre && i == 0) // 高位没有1且这一位也不是1
ans += dfs(pos - 1, num, pre, limit && i == digit[pos]);
else // 高位有1或者这一位是1
ans += dfs(pos - 1, num + (i == 0 ? 1 : -1), pre || i == 1, limit && i == digit[pos]);
}
if (!limit && pre) dp[pos][num] = ans;
return ans;
}
int cal(int x) {
int cnt = 0;
while (x) { // 存放二进制
digit[++cnt] = x & 1;
x >>= 1;
}
return cnt;
}
int main() {
int a, b;
cin >> a >> b;
memset(dp, -1, sizeof(dp));
cout << dfs(cal(b), 32, false, true) - dfs(cal(a - 1), 32, false, true) << endl;
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· 用 DeepSeek 给对象做个网站,她一定感动坏了
· DeepSeek+PageAssist实现本地大模型联网
· 手把手教你更优雅的享受 DeepSeek
· Java轻量级代码工程
· 从 14 秒到 1 秒:MySQL DDL 性能优化实战