首页 > 其他分享 >数位 dp / lianggj 让你学小专题应该怎么办

数位 dp / lianggj 让你学小专题应该怎么办

时间:2024-04-02 16:35:12浏览次数:24  
标签:return int res len limit && lianggj dp 学小

P4999

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)

using namespace std;

const int N=20, M=9*18+5, P=1e9+7; 

int t, l, r, f[N][M], a[N], len, ans;

/*
Q:查询 i in [l,r] 的 i 的数位和。
A:f[i][j] 表示任意填写 pos=1,...,i 的,以前填了 j 的数和,这个时候的任意合法情况数位和 
*/ 
int dfs(int i,bool limit,int sum) {
	if(!i) return sum; // 边界 
	if(!limit&&f[i][sum]>=0) return f[i][sum]; // 记忆化 
	int d=limit?a[i]:9, res=0; // 求一个上界 
	up(v,0,d) res=(res+dfs(i-1,limit&&v==a[i],sum+v))%P; // 枚举填什么东西 
	if(!limit) f[i][sum]=res; // 记忆化 
	return res;
}

int solve(int x) {
	len=0; // 拆位喵 
	while(x) a[++len]=x%10, x/=10;
	return dfs(len,1,0);
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	memset(f,-1,sizeof(f));
	cin >> t;
	while(t--) {
		cin >> l >> r, ans=solve(r)-solve(l-1); // 容斥成 [1,x] 的询问 
		cout << (ans%P+P)%P << '\n';
	}
	return 0;
}

P2602

#include<bits/stdc++.h>
#define int long long
#define up(i,l,r) for(int i=l; i<=r; ++i)
#define dn(i,r,l) for(int i=r; i>=l; --i)

using namespace std;

const int N=20, M=9*18+5; 

int t, l, r, f[N][M][2], a[N], len, ans[10], digit; 
/*
Q: i in [l,r] 中每个数码的出现次数,对于 digit=1,...,9 答案显然相同 
A: f[i][j][0/1] 表示任意填 pos=1,...,i,以前填了 j 个这种数码,这个数码是/不是 0 的情况下的该数码出现总次数 
*/ 

int dfs(int i,bool limit,bool lead,int cnt) {
	// 含义是填了 i+1,...,len 现在要填 i,能不能任意填写,前导 0 有没有被消除,现在填了 cnt 个数码的数码出现总次数 
	if(!i) return cnt;
	auto &now=f[i][cnt][digit!=0];
	if(!limit&&!lead&&now>=0) return now;
	int d=limit?a[i]:9, res=0;
	up(v,0,d) {
		int val=(lead&&digit==0&&v==0)?0:(cnt+(v==digit)); // 前导 0 不能算进去 >w< 
		res+=dfs(i-1,limit&&v==a[i],lead&(v==0),val); 
	}
	if(!limit&&!lead) now=res;
	return res;
}

void solve(int x,int k) {
	len=0;
	while(x) a[++len]=x%10, x/=10;
	up(i,0,9) digit=i, ans[i]+=k*dfs(len,1,1,0);
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	memset(f,-1,sizeof(f));
	cin >> l >> r;
	solve(l-1,-1), solve(r,1);
	up(i,0,9) cout << ans[i] << ' ';
	return 0;
}

标签:return,int,res,len,limit,&&,lianggj,dp,学小
From: https://www.cnblogs.com/chelsyqwq/p/18110884

相关文章

  • 状压dp板子(cf div4 #937)
    #include<bits/stdc++.h>usingnamespacestd;intn;vector<int>v[20];stringa[20],b[20];booldp[500010][20];voiddfs(ints,intnow){dp[s][now]=true;for(autonxt:v[now]){if(s&(1<<nxt))continue;......
  • RudderStack 开源CDP 平台
    RudderStack是基于golang开发的开源CDP平台包含的特性eventstreaming 支持16+sdkprofiles 快速基于dw或者datalake构建客户画像reverseetl 支持反向etl数据治理 支持增强追踪,方便对于一些隐私数据的管理event转换 支持基于js以及python进行数据修复200+......
  • 树形DP+树上路径贡献
    题目一棵树有n个节点,每个节点都同有一个符号+或者-,表示该节点是正极节点还是负极节点。如果从正极走到负极,或者从负极走到正极,都会受到1点伤害。现在需要知道走过所有路径后会受到的总伤害是多少?树上任意2点存在唯一的路径。需要计算所有任意2点的路径的伤害和。注意:从u到,和从v......
  • Offer必备算法17_子数组子串dp_八道力扣题详解(由易到难)
    目录①力扣53.最大子数组和解析代码②力扣918.环形子数组的最大和解析代码③力扣152.乘积最大子数组解析代码④力扣1567.乘积为正数的最长子数组长度解析代码⑤力扣413.等差数列划分解析代码⑥力扣978.最长湍流子数组解析代码⑦力扣139.单词拆分解析代码......
  • Offer必备算法19_子序列dp_八道力扣题详解(由易到难)
    目录①力扣300.最长递增子序列解析代码②力扣376.摆动序列解析代码③力扣673.最长递增子序列的个数解析代码④力扣646.最长数对链解析代码⑤力扣1218.最长定差子序列解析代码⑥力扣873.最长的斐波那契子序列的长度解析代码⑦力扣1027.最长等差数列解析代......
  • wordpress负载均衡
    部署的顺序先有后端web7,8,再有前端的lb-5。web7#装nginxgroupaddwww-g666useraddwww-s/sbin/nologin-M-u666-g666#你要确保,你装的所有机器,软件版本都一致,否则可能出奇怪bug#web7,web8用同一套软件,你最好自己去自建yum源cat>/etc/yum.repos.d/61.repo......
  • Matlab构建上位机:UDP测试
    参考:UDP理解及UDP的MATLAB实现MatlabUDP-CSDN博客文中代码:建立连接fclose(instrfindall);%先关闭之前可能存在的UDP%127.0.0.1即为本地u1=udp('127.0.0.1','RemotePort',8847,'LocalPort',8848);%u1的本机端口为8848,即监听所有发到8848端口的消息;%u1的远程端口为8847,......
  • CF1557D (dx)(dp技巧)
    比较有意思的一道题。看到将一个区间涂黑可以想到线段树。然后看到最少删除,想到最多保留。然后我一开始想的是贪心,对于每条线段找到前面最近的,然后对于每个高度取min即可。然后测了一下样例,寄了。会被这个hack掉对于这个,我们在做2时会把中间删了,然后做1的时候就寄了。这就说明......
  • C语言实现半定规划(Semidefinite Programming, SDP)算法
    目录前言A.建议B.简介一代码实现A.半定规划的基本概念B.使用C语言进行半定规划建模二时空复杂度A.时间复杂度B.空间复杂度C.实际考虑三优缺点A.优点B.缺点C.总结四现实中的应用前言A.建议1.学习算法最重要的是理解算法的每一步,而不是记住算法。2.......
  • DP学习笔记
    壹:线性DP所谓线性DP就是简单、容易写、易看出来的DP,这类DP经常在简单题中出现。通常在序列中用一维数组存储,矩阵中用二维数组存储。一维例子:设\(f_i\)表示前\(i\)个数中最长连续个1出现的次数。二维例子:设\(f_{i,j}\)表示从\((1,1)\)走到\((i,j)\)所需要用到的最......