ZOJ3962 数位DP

DigitEnergy Cost
(units/s)
06
12
25
35
44
55
66
73
DigitEnergy Cost
(units/s)
87
96
A6
B5
C4
D5
E5
F4

题意,电子显示器,初始时间m , 结束时间m+n-1 ,若时间超过FFFFFFFF,则从00000000开始计算。

典型的数位DP,


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);
	
	long[][] dp = new long[8][60] ;  
    int[] bit = new int[8] ;  
       
    long DP(int pos , int digSum  , boolean isend){  
        if(pos < 0){  
            return digSum ;  
        }  
        if(! isend && dp[pos][digSum] != -1) return dp[pos][digSum] ;  
        long sum = 0L ;  
        int d = isend ? bit[pos] : 15 ;  
        for(int i = 0 ; i <= d ; i++){  
            sum += DP(pos-1 ,  digSum + dig[i] , isend && (i == d) ) ;  
        }  
        if(! isend) dp[pos][digSum] = sum ;  
        return sum ;  
    }  
    int[] dig = {6 , 2 , 5 , 5 , 4 , 5 , 6 , 3 , 7 , 6 , 6 , 5 , 4 , 5 , 5 , 4} ;
    char[] hex = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'} ;
    long sum(String n){
        for(int i = 0 ; i < 8 ; i++)
        	bit[7-i] = to(n.charAt(i)) ;
        return DP(7 , 0 , true )   ;
    }  
    
    int to(char c){
    	if('0' <= c && c <= '9')
    		return c - '0' ;
    	else return c - 'A' + 10 ;
    }
    
    long turnBig(String s){
    	long num = 0 ;
    	for(int i = 0 ; i < s.length() ; i++){
    		num = num * 16 + to(s.charAt(i)) ;
    	}
    	return num ; 
    }
    
    String turnHex(long num){
    	String s = "" ;
    	while(num > 0){
    		int mod = (int) (num % 16)  ;
    		s =  hex[mod] + s ;
    		num = num / 16 ;
    	}
    	while(s.length() < 8) s = '0' + s ;
    	return s ; 
    }
    
    long calc(long l , long r){
    	if(l == 0)
    		return sum(turnHex(r)) ;
    	return sum(turnHex(r)) - sum(turnHex(l-1)) ;
    }
      
    void solve(){  
        for(int i = 0 ; i <= 7 ; i++){
        	   Arrays.fill(dp[i] , -1L) ;  
        }
        
        long limit = turnBig("FFFFFFFF") ;
        int t = in.nextInt() ;
        while(t-- > 0){  
        	long n = in.nextLong() ;
        	long left = turnBig(in.next()) ; 
        	long right = left + n -1 ;
        	long ans ; 
        	if(right <= limit)
        		ans = calc(left , right) ;
            else{
            	ans = calc(left, limit) + calc(0 , right - limit - 1) ;
            }
            out.println(ans);  
        }  
        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、付费专栏及课程。

余额充值