每日亿题--2021.5.12 数位dp

Posted 斗奋力努

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日亿题--2021.5.12 数位dp相关的知识,希望对你有一定的参考价值。

数位dp

平常考的裸的数位dp其实就是记忆化搜索,在dfs的时候可以通过多定义自己需要和想要的参数来水过去。但对于那些数位dp难题,会和其他一些知识结合起来考,也可能在计算时需要某种优化方法。
具体的以后出现了再说,这里是一道十分裸的数位dp题,大家学了数位dp后应该可以秒本题。

P4999 烦人的数学作业
在这里插入图片描述
注意:
1、多组数据读入。数据不算太大,可以多次memset(dp,-1,sizeof(dp))。当然初始一次memset(dp,-1,sizeof(dp))也是可以的。
2、注意最终结果需要mod(1e9+7)。

思路:
1、直接上数位dp通用解题模板,然后在dfs的时候加一个参数sum, 表示前pos位之和是多少,其他与模板一致。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll l,r;
ll nums[20];
ll dp[20][200];

ll dfs(ll pos,ll sum,bool limit){
	if(pos==0) return sum;
	if(!limit&&dp[pos][sum]!=-1) return dp[pos][sum];
	ll up=limit?nums[pos]:9;
	ll ans=0;
	for(ll i=0;i<=up;i++){
		ans=(ans+dfs(pos-1,sum+i,limit&&i==up))%mod;
	}
	if(!limit) dp[pos][sum]=ans;
	return ans;
}

ll solve(ll x){
	ll pos=0;
	while(x){
		nums[++pos]=x%10;
		x/=10;
	}
	return dfs(pos,0,true);
}

int main(){
	int t; cin>>t;
	memset(dp,-1,sizeof(dp));
	while(t--){
		cin>>l>>r;
		cout<<(solve(r)-solve(l-1)+mod)%mod<<endl;
	}
}

以上是关于每日亿题--2021.5.12 数位dp的主要内容,如果未能解决你的问题,请参考以下文章

每日亿题#12AtCoder Grand Contest 021 (A ~ F)全部题解

每日亿题#12AtCoder Grand Contest 021 (A ~ F)全部题解

每日亿题#12AtCoder Grand Contest 021 (A ~ F)全部题解

每日dp Gym - 101889E Enigma 数位dp 记忆化搜索

牛客每日一题 和与或 数位dp+状态压缩

力扣 每日一题 902. 最大为 N 的数字组合难度:困难,rating: 1989(数学 / 数位dp)