我是靠谱客的博主 无奈汽车,最近开发中收集的这篇文章主要介绍HDU4507(数位dp,模板),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

解题思路:dp[i][h][s]:i代表第几位数,h代表数字和对7的余数,s代表数字对7的余数。

#include<cstdio>
#include<cstring>
#define ll long long
//#define mod 1000000007LL
using namespace std;
ll mod=1e9 + 7;
ll d[20],p[20];//这边用int会超 
struct node
{
	ll sqnum,cnt,num;
	node(){
		cnt=-1;num=sqnum=0;
	}
	node(ll a,ll b,ll c):cnt(a),num(b),sqnum(c){
	}
}dp[20][8][8];
node dfs(int l,int h,int s,bool lim)
{
	if(l==0) return (h!=0&&s!=0)? node(1,0,0):node(0,0,0);//注意,求得是和7无关的 
	if(!lim&&dp[l][h][s].cnt!=-1) return dp[l][h][s];//如果没有限制了并且dp[l][h][s]前面已经得出答案了,就直接返回 
	int k= lim? d[l]:9;//如果有限制,那就最多到d[l],即后面的枚举要小于l位数 
	node tp,r=node(0,0,0);
	for(int i=0;i<=k;i++)
	{
		if(i==7) continue;
		tp=dfs(l-1,(h+i)%7,(s*10+i)%7,lim&&i==d[l]);//只有前面的数都恰好等于给定数的值,那么后面的数才是有限制的 
		r.cnt+=tp.cnt;//加上后面位中符合条件的数 
		r.cnt%=mod;
		r.num+=(tp.num+((p[l]*i)%mod)*tp.cnt%mod)%mod;//反正各种记录 
        r.num%=mod;
        r.sqnum+=(tp.sqnum+((2*p[l]*i)%mod)*tp.num)%mod;
        r.sqnum%=mod;
        r.sqnum+=((tp.cnt*p[l])%mod*p[l]%mod*i*i%mod);
        r.sqnum%=mod;
	}
	if(!lim)
	dp[l][h][s]=r;
	return r;
}
 
ll solve(ll a)
{
	int l=0;
	while(a)
	{
		d[++l]=a%10;
		a/=10;
	}
	node tp=dfs(l,0,0,true);
	return tp.sqnum;
}
int main()
{
	freopen("t.txt","r",stdin);
	ll T,a,b;
	scanf("%d",&T);
	p[1]=1;
    for(int i=2;i<=20;i++) p[i]=(p[i-1]*10)%mod;
    //printf("%lldn",mod); 
	while(T--)
	{
		scanf("%lld%lld",&a,&b);
		ll ans=solve(b)-solve(a-1);
		printf("%lldn",(ans%mod+mod)%mod);//可能两个相减为负数,所以要变成正的 
	}
	return 0;
}

 

最后

以上就是无奈汽车为你收集整理的HDU4507(数位dp,模板)的全部内容,希望文章能够帮你解决HDU4507(数位dp,模板)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部