您的位置:首页 > 其它

self 同类分布 (数位dp)

2017-11-02 00:12 232 查看
给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数。Sample Input
10 19

Sample Output
3

Hint
【约束条件】1 ≤ a ≤ b ≤ 10^18

题目大概:

题目比较简短。

思路:

这个题时间限制比较大,数据又比较大,所以可以枚举各位数字之和来解决问题,因为最多18位,最大为9,所以各位和最大为162。

枚举各位和,找出符合题目要求的条件的数字的个数,即列两个状态就可以了。

注意精度!

代码:

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>

using namespace std;
typedef long long ll;
ll a[22],f[22];
ll dp[22][163][163][2];

ll dpp(int pos,int sum,int b,int mo,bool limit)
{
if(!pos)return sum==0&&b==0;
if(dp[pos][sum][b][limit]!=-1)return dp[pos][sum][b][limit];
ll sun=0;
int end=limit?a[pos]:9;
for(int i=0;i<=end;i++)
{
if(sum-i<0)break;
sun+=dpp(pos-1,sum-i,(b*10+i)%mo,mo,limit&&i==a[pos]);

}
dp[pos][sum][b][limit]=sun;
return sun;
}

ll go(ll x)
{
int pos=0;
while(x)
{
a[++pos]=x%10;
x/=10;
}
ll ans=0;
for(int mo=1;mo<=pos*9;mo++)
{
memset(dp,-1,sizeof(dp));
ans+=dpp(pos,mo,0,mo,1);
}
return ans;
}

int main()
{
ll n,m;
while(~scanf("%lld%lld",&n,&m))
{
printf("%lld\n",go(m)-go(n-1));
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息