2020ICPC上海 C题(数位dp, 记忆化搜索)
先复习了下之前做的数位DP又做了道新题才看的这道题,对我来说还是一种新类型,涉及到非线性计算,之前做的都是形如 \(dp[x]-dp[y]\)这样的只用处理一个上限做下差即可。一开始想分别枚举 \(x\)和 \(y\)中最高位 \(1\)的位置,计算符合要求的组合数目,但是一旦两个数的最高位 \(1\)是上限的时候感觉处理起来会很麻烦,需要分很多种讨论,而且情况还不好处理,容易缺漏。然后看了下题解,它是数位DP的思想加上记忆化搜索,它直接枚举最高位 \(1\)的位置,然后计算有多少种组合满足要求。状态数组为 \(dp[bit][is\_1][is\_2][ok]\),第一维代表枚举的位数,第二、三维代表两个数的第 \(bit\)位是否被锁定,如果被锁定则该位取值不能大于原数该位的值,实际上是在限制这两个数不能大于原数,第四维代表两数的或运算结果在第 \(bit\)位是否必须为 \(1\)。然后记忆化搜索统计答案。
#include<cstdio>
#include<cstring>
const int mod = 1e9 + 7;
int T, x, y;
int dp[35][2][2][2];
inline int max(int a, int b) { return a > b ? a : b; }
// ok=1代表当前枚举的两个数的第bit位的|必须为1
int dfs(int bit, bool is_1, bool is_2, bool ok){
if(bit == -1) return 1;
if(dp[bit][is_1][is_2][ok]) return dp[bit][is_1][is_2][ok];
int temp = 0;
// 上界
int k1 = is_1 ? (x >> bit & 1) : 1;
int k2 = is_2 ? (y >> bit & 1) : 1;
//printf("%d %d %d", bit, k1, k2);
for(int i = 0; i <= k1; ++i)
for(int t = 0; t <= k2; ++t){
if(i & t) continue;
// 此后不必要求两数之|为1,ok=0
if(ok){
if(i | t) temp = (temp + dfs(bit - 1, is_1 && (i == k1), is_2 && (t == k2), 0)) % mod;
}
else{
temp = (temp + dfs(bit - 1, is_1 && (i == k1), is_2 && (t == k2), 0)) % mod;
}
}
return dp[bit][is_1][is_2][ok] = temp;
}
int main(){
scanf("%d", &T);
while(T--){
int ans = 0;
memset(dp, 0, sizeof(dp));
scanf("%d%d", &x, &y);
int a = x, b = y, da = -1, db = -1;
for(; a; a >>= 1) ++da;
for(; b; b >>= 1) ++db;
for(int i = max(da, db); i >= 0; --i){
// 因为正在统计第i位的答案,只有两数之|在第i位为1才有贡献,所以ok=1
ans = (ans + 1LL * dfs(i, i >= da, i >= db, 1) * (i + 1)) % mod;
}
printf("%d\n", ans);
}
return 0;
}
2020ICPC上海 C题(数位dp, 记忆化搜索)的更多相关文章
- [hihocoder 1033]交错和 数位dp/记忆化搜索
#1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描写叙述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1 ...
- 【poj1850】 Code 数位dp+记忆化搜索
题目大意:给你一个字符串,问你这个字符串的rank,如果这个字符串不合法,请直接输出0.(一个合法的字符串是对于∀i,有c[i]<c[i+1]) 字符串s的rank的计算方式:以字符串长度作为第 ...
- bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)
1833: [ZJOI2010]count 数字计数 题目:传送门 题解: 今天是躲不开各种恶心DP了??? %爆靖大佬啊!!! 据说是数位DP裸题...emmm学吧学吧 感觉记忆化搜索特别强: 定义 ...
- 1026-windy数+数位DP+记忆化搜索
1026: [SCOI2009]windy数 题意:数位DP模板题: 目前只理解了记忆化搜索,就想练练手, ------给递推写法留一个位子 ------ 注意这道题要判断前导0的情况,1 )可以加一 ...
- 数位dp/记忆化搜索
一.引例 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an ...
- [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)
3598: [Scoi2014]方伯伯的商场之旅 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 449 Solved: 254[Submit][Sta ...
- 【每日dp】 Gym - 101889E Enigma 数位dp 记忆化搜索
题意:给你一个长度为1000的串以及一个数n 让你将串中的‘?’填上数字 使得该串是n的倍数而且最小(没有前导零) 题解:dp,令dp[len][mod]为是否出现过 填到第len位,余数为mod 的 ...
- luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索
题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...
- hdu3652 数位dp记忆化搜索
从未见过的船新版本数位dp,,省去了预处理过程,直接进行计算 #include<bits/stdc++.h> using namespace std; #define ll long lo ...
- cf55D 数位dp记忆化搜索+状态离散
/* 漂亮数定义:可以整除任意数位上的数 求出区间[l,r]之间的漂亮数个数 因为 dp[i][j][k]:i位前模lcm的值是j,i位前lcm是k的漂亮数个数 */ #include<bits ...
随机推荐
- 利用选项卡提高Visual Studio 2022开发效率
设计器作为软件开发的必要工具,其效率的提高显得尤为重要.Visual Studio 2022作为一款功能强大的设计器,通过选项卡提高了工作效率,让开发者在使用过程中更加便捷. 在Visual Stud ...
- Jmeter+Ant+Jenkins接口自动化测试平台
一个完整的接口自动化测试平台需要支持接口的自动执行,自动生成测试报告,以及持续集成. Jmeter 支持接口的测试, Ant 支持自动构建,而 Jenkins 支持持续集成,所以三者组合在一起可以构成 ...
- 让 GPT-4 来修复 Golang “数据竞争”问题(续) - 每天5分钟玩转 GPT 编程系列(7)
目录 1. 我以为 2. 阴魂不散的"数据竞争"问题 3. 老规矩,关门放 GPT-4 3.1 复现问题 3.2 让 GPT-4 写一个单元测试 3.3 修复 Wait() 中的逻 ...
- [ABC132D] Blue and Red Balls
2023-01-16 题目 题目传送门 翻译 翻译 难度&重要性(1~10):3 题目来源 AtCoder 题目算法 dp 解题思路 因为蓝球的数量是固定的,题目让我们求,在取 \(i\) 次 ...
- LR性能分析
如何模拟真实用户的行为 真实用户的操作是否可预期,比如考试 用户一般会先打开考试页面,然后答题 那么会有多种题型,用户是不是有可能答不同的题型 性能的拐点
- Spring Bean 的作用域(Bean Scope)
前言 大家好,我是 god23bin,今天我们来聊一聊 Spring 框架中的 Bean 作用域(Scope). 什么是 Bean 的作用域? 我们在以 XML 作为配置元数据的情况下,进行 Bean ...
- Springboot+Mybatisplus+ClickHouse集成
核心依赖引入 <dependency> <groupId>ru.yandex.clickhouse</groupId> <artifactId>clic ...
- ArcGIS地图投影与坐标系转换的方法
本文介绍在ArcMap软件中,对矢量图层或栅格图层进行投影(即将地理坐标系转为投影坐标系)的原理与操作方法. 首先,地理坐标系与投影坐标系最简单的区别就是,地理坐标系用经度.纬度作为空间衡量指 ...
- 聊聊基于Alink库的推荐系统
概述 Alink提供了一系列与推荐相关的组件,从组件使用得角度来看,需要重点关注如下三个方面: 算法选择 推荐领域有很多算法,常用的有基于物品/用户的协同过滤.ALS.FM算法等.对于不同的数据场景, ...
- 深入理解 Socket 编程:网络通信的基石
深入理解 Socket 编程:网络通信的基石 引言 在现代计算机网络中,网络通信是各种应用程序之间进行数据交换和信息传输的基础.Socket 编程是实现网络通信的关键组件之一,它提供了一种方便而强大的 ...