记忆化搜索版,比较有套路

就根据杠杆数这道题来回忆一下

题目大致意思:选定大数中的某个数作为支点,使左右两边的力矩和相等,求区间内能满足条件的数的个数

首先一个大前提:对于一个满足条件的数来说,他的支点确定

如何证明:以将支点向左移动为例,支点左侧的力矩和因为支点向左移动,导致整体的力矩减少,并且数字个数减少一个,其他数字不变,所以可证,左边的力矩和减小,右边的力矩和增大,找不出第二个支点位置,可以使两边的力矩和相等

整体做法:枚举支点的位置,进行dp

一些细节:

  1. 我们不用分清左右,当位置在左时pos-x为负,当位置在右时,pos-x为正,这样我们只要保证最后的力矩和为0就ok了

  2. 当力矩和 < 0时不用继续向下搜索,因为我们是从右往左挨个位置依次搜索,所以左边为正的力矩已经全部计算完毕,当为负时,只会越减越少

  3. 一些数位dp的套路(是否有前导0,是否有数字的最大限制),最开始的初始化为1

  4. 因为每次枚举支点会把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;
}

最新文章

  1. Html5知识
  2. jenkins入门
  3. linux环境下安装mongodb
  4. Virtualbox修改bios信息安装Windows XP OEM
  5. Codeforces Round #343 (Div. 2) C. Famil Door and Brackets
  6. LintCode: isSubTree
  7. iOS Development Learning 13Nov
  8. Android 70道面试题汇总
  9. &quot;sessionFactory &quot; or &quot;hibernateTemplate &quot; is required异常
  10. 0x3f3f3f3f...编程中无穷大常量的设置技巧
  11. eclipse+Java2WSDL+WSDL2Java 2012-12-06 12:32:43| 分类: j2ee |报道|字体大小 认购 一、eclipse如何使用低axis生成wsdl 可以使用
  12. Oracle第二天
  13. 当业务逻辑没错,直接mapper里面出错时
  14. three.js 3d三维网页代码加密的实现方法
  15. kvm键盘使用
  16. [Spring]初识Spring-Spring是什么?如何实例化一个Spring容器?
  17. Java中常见流的分类及简单讲解
  18. 尚硅谷redis学习5-初识redis.conf
  19. VBA学习笔记(2)--新建word文档并插入文字
  20. Ubuntu 16.04安装Vim8.0

热门文章

  1. ros_navigation案列操作流程
  2. H3C MS4300V2配置mac地址与接口绑定
  3. 用 HTTP 协议下载资源(WinINet 实现)
  4. 详解神经网络基础部件BN层
  5. php .inc 文件
  6. Roadblocks
  7. KMP字符串 AcWing 831
  8. corundum:100GNIC学习(三)——恢复工程
  9. 浅析容器运行时奥秘——OCI标准
  10. ubuntu20.04安装fastdfs遇到的问题