hdu5787 数位DP

Problem Description
Alice thinks an integer x is a K-wolf number, if every K adjacent digits in decimal representation of x is pairwised different.
Given (L,R,K), please count how many K-wolf numbers in range of [L,R].
 

Input
The input contains multiple test cases. There are about 10 test cases.

Each test case contains three integers L, R and K.

1LR1e18
2K5
 

Output
For each test case output a line contains an integer.
 

Sample Input
  
  
1 1 2 20 100 5
 

Sample Output
  
  
1 72

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;


public class Main {
	public static void main(String[] args) {
		new Task().solve();
	}
}

class Task{
	InputReader in = new InputReader(System.in) ;
	PrintWriter out = new PrintWriter(System.out) ;
	
	int[] bit = new int[19] ;
	long[][][][][] dp = new long[19][11][11][11][11] ; 
	int K ;
	
	long dfs(int pos , int one , int two , int three , int four , boolean isEnd){
		if(pos == -1){
			return four == 10 ? 0 : 1 ;
		}
		if(!isEnd && dp[pos][one][two][three][four] != -1){
			return dp[pos][one][two][three][four] ;
		}
		int d = isEnd ? bit[pos] : 9 ;
		long sum = 0 ;
		for(int i = 0 ; i <= d ; i++){
			if(i == 0 && four == 10){
				sum += dfs(pos-1 , 10 , 10 , 10 , 10 , isEnd && i == d) ;
			}
			else{
				boolean cango = true ;
				int[] now = {one , two , three , four} ;
				for(int k = 3 ; k >= 5 - K ; k--){
					if(i == now[k]){
						cango = false ;
						break ;
					}
				}
				if(cango){
					sum += dfs(pos-1 , two, three, four, i , isEnd && i == d) ;
				}
			}
		}
		if(! isEnd){
			dp[pos][one][two][three][four] = sum ;
		}
		return sum ;
	}
	
	long calc(long n){
		int pos = 0 ; 
		while(n > 0){
			bit[pos++] = (int) (n % 10) ;
			n /= 10 ;
		}
		return dfs(pos-1 , 10 , 10 , 10 , 10 , true) ;
	}
	
	void fill(){
		for(int a = 0 ; a < 19 ; a++){
			for(int b = 0 ; b < 11 ; b++){
				for(int c = 0 ; c < 11 ; c++){
					for(int d = 0 ; d < 11 ; d++){
						Arrays.fill(dp[a][b][c][d] ,-1) ;
					}
				}
			}
		}
	}
	
	void solve(){
		while(in.hasNext()){
			long l = in.nextLong() ;
			long r = in.nextLong() ;
			K = in.nextInt() ;
			fill();
			out.println(calc(r) - calc(l-1)) ;
		}
		out.flush();
	}
}

class InputReader {  
    public BufferedReader reader;  
    public StringTokenizer tokenizer;  
  
    public InputReader(InputStream stream) {  
        reader = new BufferedReader(new InputStreamReader(stream), 32768);  
        tokenizer = new StringTokenizer("");  
    }   
  
    private void eat(String s) {  
        tokenizer = new StringTokenizer(s);  
    }  
  
    public String nextLine() {  
        try {  
            return reader.readLine();  
        } catch (Exception e) {  
            return null;  
        }  
    }  
  
    public boolean hasNext() {  
        while (!tokenizer.hasMoreTokens()) {  
            String s = nextLine();  
            if (s == null)  
                return false;  
            eat(s);  
        }  
        return true;  
    }  
  
    public String next() {  
        hasNext();  
        return tokenizer.nextToken();  
    }  
  
    public int nextInt() {  
        return Integer.parseInt(next());  
    }  
  
    public long nextLong() {  
        return Long.parseLong(next());  
    }  
  
    public double nextDouble() {  
        return Double.parseDouble(next());  
    }  
  
    public BigInteger nextBigInteger() {  
        return new BigInteger(next());  
    }  
  
}  




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值