码迷,mamicode.com
首页 > 其他好文 > 详细

数位dp小结

时间:2019-01-28 23:08:25      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:while   tin   def   amp   ios   view   数位   string   span   

思路:逐位处理,在依次遍历十进制的每一位数字的基础上不断更新状态,从而求解dp[i][s]表示第i位,状态为s的数字的个数。

 

例题一:传送门

思路:求和,然后对N取余。

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
LL A,B,N,a[120],dp[50][120];
LL dfs(LL pos,LL stu,bool done)
{
    if(pos==-1) return stu%N==0?1:0;
    if(!done&&~dp[pos][stu]) return dp[pos][stu];
    LL tp,len=(done?a[pos]:9),i,ans=0;
    for(i=0;i<=len;i++){
        tp=(stu+i)%N;
        ans+=dfs(pos-1,tp,done&&(i==len));
    }
    if(!done) dp[pos][stu]=ans;
    return ans;
}
LL solve(LL x)
{
    memset(dp,-1,sizeof(dp));
    LL pos=0;
    while(x){
        a[pos++]=x%10;x/=10;
    }
    return dfs(pos-1,0,true);
}
int main(void)
{
    while(~scanf("%lld%lld%lld",&A,&B,&N)){
        printf("%lld\n",solve(B)-solve(A-1));
    }
    return 0;
}
View Code

 

例题二(hdu-2089):传送门

思路:判断62(前一个状态和后一个状态),判断4。

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[120][50],a[50],n,m;
int dfs(int pos,int stu,bool done)
{
    if(pos==-1) return 1;
    if(!done&&~dp[pos][stu]) return dp[pos][stu];
    int tp,len=(done?a[pos]:9),i,ans=0;
    for(i=0;i<=len;i++){
        if(i==4||(stu==6&&i==2)) continue;
        ans+=dfs(pos-1,i,done&&(len==i));
    }
    if(!done) dp[pos][stu]=ans;
    return ans;
}
int solve(int x)
{
    memset(dp,-1,sizeof(dp));
    int pos=0;
    while(x){
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,0,true);
}
int main(void)
{
    while(~scanf("%d%d",&n,&m)&&(n+m)){
        if(n>m){
            int tp=n;n=m;m=tp;
        }
        printf("%d\n",solve(m)-solve(n-1));
    }
    return 0;
}
View Code

 

数位dp小结

标签:while   tin   def   amp   ios   view   数位   string   span   

原文地址:https://www.cnblogs.com/2018zxy/p/10332043.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!