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

hdu5787(数位dp)

时间:2016-08-10 22:42:06      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

基础的数位dp,才发现今天才终于彻底搞懂了数位dp。。。

//
//  main.cpp
//  hdu5787.1
//
//  Created by New_Life on 16/8/10.
//  Copyright © 2016年 chenhuan001. All rights reserved.
//

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;

long long dp[20][5][10010];
int k;
int mod;

long long dfs(int wei[],int p,int flag,long long pre,int pk)
{
    if(p<0) return 1;
    if(flag  == 0  && dp[p][pk][pre]!= -1) return dp[p][pk][pre];
    int mark[10];
    int twei[6];
    memset(mark,0,sizeof(mark));
    memset(twei,0,sizeof(twei));
    long long tp = pre;
    int cnt = 0;
    while(tp)
    {
        twei[ cnt++ ] = tp%10;
        tp/=10;
    }
    for(int i=0;i<pk;i++) mark[twei[i]]++;
    
    if(flag == 1)
    {
        long long sum = 0;
        for(int i=0;i<wei[p];i++)
        {
            if(pk==0 && i==0)
            {
                sum += dfs(wei,p-1,0,0,0);
            }
            else
            {
                if(mark[i]==0)
                    sum += dfs(wei,p-1,0,(pre*10+i)%mod,min(pk+1,k-1));
            }
        }
        if(mark[wei[p]]==0) sum += dfs(wei,p-1,1,(pre*10+wei[p])%mod,min(pk+1,k-1));
        return sum;
    }
    else
    {
        long long sum = 0;
        for(int i=0;i<=9;i++)
        {
            if(pk==0 && i==0)
            {
                sum += dfs(wei,p-1,0,0,0);
            }
            else
            {
                if(mark[i]==0)
                {
                    sum += dfs( wei,p-1,0,(pre*10+i)%mod,min(pk+1,k-1) );
                }
            }
        }
        return dp[p][pk][pre]=sum;
    }
}

long long get(long long x)
{
    if(x==0) return 1;
    memset(dp,-1,sizeof(dp));
    int wei[20];
    int cnt = 0;
    while(x)
    {
        wei[cnt++] = x%10;
        x /= 10;
    }
    return dfs(wei,cnt-1,1,0,0);
}

int main(int argc, const char * argv[]) {
    long long L,R;
    while (cin>>L>>R>>k) {
        mod = (int)pow(10.0,k-1);
        cout<<get(R)-get(L-1)<<endl;
//        int ans = 0;
//        for(int i=L;i<=R;i++)
//        {
//            int wei[10];
//            memset(wei, 0, sizeof(wei));
//            int ti = i;
//            int cnt = 0;
//            while(ti)
//            {
//                wei[ cnt++ ] = ti%10;
//                ti/=10;
//            }
//            int flag = 0;
//            for(int j=1;j<cnt;j++)
//            {
//                for(int p=1;p<k;p++)
//                {
//                    if(j-p>=0 && wei[j-p]==wei[j] )
//                    {
//                        flag = 1;
//                        break;
//                    }
//                }
//                if(flag) break;
//            }
//            if(flag == 0) ans++;
//        }
//        printf("right: %d\n",ans);
    }
    return 0;
}
/*
 1 1 2
 20 100 5
 101 101 3
 100 200 2
*/

 

hdu5787(数位dp)

标签:

原文地址:http://www.cnblogs.com/chenhuan001/p/5758956.html

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