zoukankan      html  css  js  c++  java
  • HDU 5787 K-wolf Number 数位dp

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5787

    K-wolf Number

    Time Limit: 6000/3000 MS (Java/Others)
    Memory Limit: 65536/65536 K (Java/Others)
    #### 问题描述 > 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]. #### 输入 > The input contains multiple test cases. There are about 10 test cases. > > Each test case contains three integers L, R and K. > > 1≤L≤R≤1e18 > 2≤K≤5

    输出

    For each test case output a line contains an integer.

    样例

    sample input
    1 1 2
    20 100 5

    sample output
    1
    72

    题意

    求L到R之间的所有的满足十进制表示中任意相邻的k位数字都不相同的数

    题解

    数位dp,注意处理下前导零。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<map>
    #define bug(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
    
    const int maxn = 20;
    typedef __int64 LL;
    //vector<int> 存放第i-k+1位到第i位的数
    map<vector<int>, LL> dp[maxn];
    int k;
    
    //判断第0到k-2是否与k-1相同
    bool ok(const vector<int>& ve) {
    	int last = ve[k - 1];
    	for (int i = 0; i < k - 1; i++) {
    		if (last == ve[i]) return false;
    	}
    	return true;
    }
    
    int arr[maxn],tot;
    //ismax标记表示前驱是否是边界值,为true代表前驱都是边界值,为false则说明前驱已经小于边界了,这一位可以任意取了。
    //iszer表示前驱是否都为0,即前面几位是否都为0
    //vec记录的是前驱的结尾的k位
    LL dfs(int len,vector<int> vec, bool ismax,bool iszer) {
    	if (len == 0) {
    		//递归边界,这说明前驱都合法了
    		return 1LL;
    	}
    	if (!ismax&&dp[len].count(vec)) return dp[len][vec];
    	LL res = 0;
    	int ed = ismax ? arr[len] : 9;
    	vector<int> ve;
    	for (int i = 1; i < vec.size(); i++) {
    		//这里吧前导零的部分贴成负数,防止当成真正的0来判。
    		if (iszer) ve.push_back(-i);
    		else ve.push_back(vec[i]);
    	}
    	
    	for (int i = 0; i <= ed; i++) {
    		ve.push_back(i);
    		if (ok(ve)) {
    			res += dfs(len - 1, ve, ismax&&i == ed,iszer&&i==0);
    		}
    		ve.pop_back();
    	}
    	return ismax ? res : dp[len][vec] = res;
    }
    
    LL solve(LL x) {
    	tot = 0;
    	while (x) { arr[++tot] = x % 10; x /= 10; }
    	vector<int> vec;
    	for (int i = 1; i <= k; i++) vec.push_back(-i);
    	return dfs(tot, vec, true,true);
    }
    
    void init() {
    	for (int i = 0; i < maxn; i++) dp[i].clear();
    }
    
    int main() {
    	LL x, y;
    	init();
    	while (scanf("%I64d%I64d%d",&x,&y,&k)==3) {
    		printf("%I64d
    ", solve(y)-solve(x-1));
    	}
    	return 0;
    }
  • 相关阅读:
    推荐一款idea 翻译插件 ECTranslation
    idea 执行maven 命令
    Future Clalback使用案例
    newCachedThreadPool使用案例
    线程池 原理学习笔记
    使用curator框架简单操作zookeeper 学习笔记
    mongo aggregate 用法记录
    ReentrantLock 学习笔记
    VUE:过渡&动画
    VUE:生命周期
  • 原文地址:https://www.cnblogs.com/fenice/p/5731315.html
Copyright © 2011-2022 走看看