# 【BZOJ-2063】我爸是李刚 数位dp 好题

## 2063: 我爸是李刚

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 139  Solved: 72
[Submit][Status][Discuss]

40 218 57

29

## HINT

100%的数据 l,r<=10^18 ,M<=1000 50%的数据，r-l<=10^6

## Code

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
#define LL long long
#define Pa pair<LL,LL>
#define sum first
#define res second
#define MP make_pair

LL L,R,M;
int dl[19],dr[19],len;

Pa dp[19][210][1010];

Pa operator + (const Pa &A,const Pa &B) {return MP(A.sum+B.sum,B.res);}

inline Pa DP(int dep,LL sum,LL res,bool f,bool g)
{
if (!dep) return (sum+res>=M? MP(1LL,0LL):MP(0LL,sum+res));
if (!f && !g && ~dp[dep][sum][res].sum) return dp[dep][sum][res];
Pa ret=MP(0,res);
for (int i=(f? dl[dep]:0); i<=(g? dr[dep]:9); i++)
ret=ret+DP(dep-1,sum+i,ret.res,f && i==dl[dep],g && i==dr[dep]);
if (!f && !g) dp[dep][sum][res]=ret;
return ret;
}

int main()
{
scanf("%lld%lld%lld",&L,&R,&M);
len=0; while (L) dl[++len]=L%10,L/=10;
len=0; while (R) dr[++len]=R%10,R/=10;
for (int i=1; i<=18; i++)
for (int j=0; j<=200; j++)
for (int k=0; k<=1000; k++)
dp[i][j][k]=MP(-1,0);
printf("%lld\n",DP(len,0,0,1,1).sum);
return 0;
}


——It's a lonely path. Don't make it any lonelier than it has to be.
posted @ 2017-03-19 20:28  DaD3zZ  阅读(578)  评论(0编辑  收藏  举报