算法学习—————数位dp
记忆化搜索版,比较有套路
就根据杠杆数这道题来回忆一下
题目大致意思:选定大数中的某个数作为支点,使左右两边的力矩和相等,求区间内能满足条件的数的个数
首先一个大前提:对于一个满足条件的数来说,他的支点确定
如何证明:以将支点向左移动为例,支点左侧的力矩和因为支点向左移动,导致整体的力矩减少,并且数字个数减少一个,其他数字不变,所以可证,左边的力矩和减小,右边的力矩和增大,找不出第二个支点位置,可以使两边的力矩和相等
整体做法:枚举支点的位置,进行dp
一些细节:
我们不用分清左右,当位置在左时pos-x为负,当位置在右时,pos-x为正,这样我们只要保证最后的力矩和为0就ok了
当力矩和 < 0时不用继续向下搜索,因为我们是从右往左挨个位置依次搜索,所以左边为正的力矩已经全部计算完毕,当为负时,只会越减越少
一些数位dp的套路(是否有前导0,是否有数字的最大限制),最开始的初始化为1
因为每次枚举支点会把0000000……给计算上,所以最后的答案为ans-cnt+1
其实我在很多算法上,了解的都不是很深刻,有的算法甚至只是会做某一道题目,自己的道路还很漫长
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#define B cout<<"Breakpoint"<<endl;
#define O(x) cout<<#x<<" "<<x<<endl;
#define int long long
using namespace std;
int read(){
int x = 1,a = 0;char ch = getchar();
while (ch < '0'||ch > '9'){if (ch == '-') x = -1;ch = getchar();}
while (ch >= '0'&&ch <= '9'){a = a*10+ch-'0';ch = getchar();}
return x*a;
}
int a,b;
int dp[20][20][2005],num[2005];
int dfs(int pos,int x,bool flag,bool lim,int sum){
if (!pos) return sum == 0;
if (sum < 0) return 0;
if (!lim&&dp[pos][x][sum] != -1) return dp[pos][x][sum];
int maxx = lim ? num[pos] : 9,ans = 0;
for (int i = 0;i <= maxx;i++){
if (flag) ans += dfs(pos-1,x,i == 0,lim&&i == maxx,sum+i*(pos-x));
else ans += dfs(pos-1,x,0,lim&&i == maxx,sum+i*(pos-x));
}
if (!flag&&!lim) return dp[pos][x][sum] = ans;
return ans;
}
int solve(int x){
int ans = 0,cnt = 0;
while (x){
num[++cnt] = x % 10;
x /= 10;
}
for (int i = 1;i <= cnt;i++) ans += dfs(cnt,i,1,1,0);
return ans-cnt+1;
}
signed main(){
memset(dp,-1,sizeof(dp));
a = read(),b = read();
if (!a) cout<<solve(b)<<endl;
else cout<<solve(b) - solve(a-1)<<endl;
return 0;
}
算法学习—————数位dp的更多相关文章
- 算法笔记--数位dp
算法笔记 这个博客写的不错:http://blog.csdn.net/wust_zzwh/article/details/52100392 数位dp的精髓是不同情况下sta变量的设置. 模板: ]; ...
- 【算法】数位 dp
时隔多日,我终于再次开始写博客了!! 上午听了数位 dp,感觉没听懂,于是在网上进行一番愉 ♂ 快 ♀ 的学习后,写篇博来加深一下印象~~ 前置的没用的知识 数位 不同计数单位,按照一定顺序排列,它们 ...
- 算法复习——数位dp
开头由于不知道讲啥依然搬讲义 对于引入的这个问题,讲义里已经很清楚了,我更喜欢用那个建树的理解···· 相当于先预处理f,然后从起点开始在树上走··记录目前已经找到了多少个满足题意的数k,如果枚举到第 ...
- 算法复习——数位dp(不要62HUD2089)
题目 题目描述 杭州人称那些傻乎乎粘嗒嗒的人为 62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司 ...
- 省选算法学习-插头dp
插头dp?你说的是这个吗? 好吧显然不是...... 所谓插头dp,实际上是“基于连通性的状态压缩dp”的简称,最先出现在cdq的论文里面 本篇博客致力于通过几道小小的例题(大部分都比较浅显)来介绍一 ...
- 动态规划——数位dp
通过先前在<动态规划——背包问题>中关于动态规划的初探,我们其实可以看到,动态规划其实不是像凸包.扩展欧几里得等是具体的算法,而是一种在解决问题中决策的思想.在不同的题目中,我们都需要根据 ...
- 掌握数位dp
最近遇到了数位dp题目,于是就屁颠屁颠的跑过来学习数位dp了~ "在信息学竞赛中,有这样一类问题:求给定区间中,满足给定条件的某个D 进制数或此类数的数量.所求的限定条件往往与数位有关,例如 ...
- HDU 2089 数位dp入门
开始学习数位dp...一道昨天看过代码思想的题今天打了近两个小时..最后还是看了别人的代码找bug...(丢丢) 传说院赛要取消 ? ... 这么菜不出去丢人也好吧~ #include<stdi ...
- Hdu 4734 【数位DP】.cpp
题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...
- 【HDU】6148 Valley Numer 数位DP
[算法]数位DP [题意]定义V-number为从左到看单位数字未出现先递增后递减现象的数字,求0~N中满足条件的数字个数.T<=200,lenth(n)<=100 [题解]百度之星201 ...
随机推荐
- C#NPOI操作Excel,实现Excel数据导入导出(支持多个sheet)
首先在项目中引用NPOI,通过管理NuGet程序包,搜索NPOI,选择版本2.3.0(支持.NET Framework 4.0)根据自己项目选择适当版本. 1.NpoiExcelHelper.cs ...
- The Missing Semester - 第一讲 学习笔记
The Missing Semester - 第一讲 学习笔记 第一讲 课程概览与 shell 课程视频地址: https://www.bilibili.com/video/BV1Eo4y1d7KZ/ ...
- centos7中配置vnc服务多用户
我用的本地yum源. 注意: 在配置root用户时,设置vnc密码.vncpasswd 添加普通用户时,要先在root用户下添加普通用户(如:vnc1,vnc2) useradd vnc1 passw ...
- 安卓逆向 IDA 静态调试分析
1.找到我们分析的接口 2.F5进入C伪代码 修正一下参数,IDA无法正常识别 jstring __fastcall Java_com_example_sfs_MainActivity_getText ...
- [COCI2010-2011#6] STEP
题目大意 维护一个 \(01\) 序列最长的连续相邻两个数不同的子序列的长度 解析 很裸的线段树题... 要维护的信息很多 区间长度 区间最左端点 区间最右端点 区间最长前缀 区间最长后缀 区间最终的 ...
- 3D场景建模零代码平台
3D场景建模软件(零基础.零代码.**),是指用来制作场景的软件,分为2D建模和3D建模,二者使用的技术及原理不同. 2D软件:它是用3维几何图形绘制出三维图形的软件,其主要功能是利用软件中已经画好的 ...
- 使用 UnoCSS shortcuts 简化 class
UnoCSS 确实简化了不少样式书写.也降低了 CSS 打包体积,提升了样式使用率.但样式太多的话,class 也写得多,比较费眼.所幸,UnoCSS 提供了 shortcuts 来简化 class, ...
- P5318 【深基18.例3】查找文献题解(链式前向星)
P5318 [深基18.例3]查找文献题解 用head记录这一起点的最后一条边, next记录这一起点的上一条边. 注意要按照参考文献的倒叙排序(要按顺序看,而链式前向星是逆着来的,也就是为什么最简单 ...
- 狂神--ElasticSearch
一.ElasticSearch概述 官网:https://www.elastic.co/cn/downloads/elasticsearch Elaticsearch,简称为es,es是一个开源的高扩 ...
- JAVA线段树模板
public class LineTree{ int[] tree,nums; int n; public LineTree(int[] nums){ this.nums = nums; n = nu ...