算法学习—————数位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 ...
随机推荐
- P16_发布-小程序的推广与运行数据的查看
协同工作和发布 - 发布上线 基于小程序码进行推广 相对于普通二维码来说,小程序码的优势如下: 在样式上更具辨识度和视觉冲击力 能够更加清晰地树立小程序的品牌形象 可以帮助开发者更好地推广小程序 获取 ...
- SRS视频服务器CallBack的Demo
1.安装环境(很麻烦,可以选择编译启动) 官方文档快速开始docker配置: docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 -d ...
- voxel体素网络滤波器
1.简介 在进行建图的时候,由于多个视角内存在视野重叠,即多个摄像头看到同样的像素点,这样在重叠区域内会存在大量的位置十分相近的点,这会占用很多内存空间.体素网络滤波保证了在某个一定大小的立方体内只有 ...
- Spring Cloud Openfeign Get请求发生405错误
kust-retrieve服务 @Resource private AuthFeignService authFeignService; @ApiOperation("获取用户信息" ...
- dataset的基本使用
在折线图(柱状.散点图类似)中使用 案例一(默认方式) let option={ dataset:{ source:[ ["1","2","3&quo ...
- JZOJ 5062. 【GDOI2017第二轮模拟day1】航海舰队
\(\text{Solution}\) 这还是 [Lydsy2017省队十连测] 的题 不得不说 \(FFT\) 在字符串匹配中的妙啊! 前面做了道一维的题,现在这是二维的 从题目入手,不考虑可不可达 ...
- JZOJ 1083. 【GDOI2006】拯救亚特兰蒂斯
\(\text{Solution}\) 自己的网络流技术太拉了 连这样的题都做不出来 对于一个怪物,剑术和法术两样东西有一样就可以了 不难想到二分图中最小点覆盖,一条边只有两个端点之一被选就被覆盖了 ...
- Blender插件:水滴生成器(Droplet Generator)
推荐:将 NSDT场景编辑器 加入你的3D开发工具链. 原文地址:https://www.mvrlink.com/droplet-generator/ 1.官方介绍: 适用于Blender 3.1及更 ...
- C# WCF实现聊天室功能
1.WCF是什么 Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架 看这篇文章之前,可以先看我的另一篇文章,初步了解一下WCF: ...
- 华为S6720S-S24S28X-A配置参数