HDU 5787 K-wolf Number
2016-08-04 10:32
211 查看
转载声明:http://blog.csdn.net/chy20142109/article/details/52103601
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5787
题意:
给你一个区间的【L,R】的数字,然后给你一个K,求要使连续K位都不会重复的数字的个数.
![](http://img.blog.csdn.net/20160804095311972)
例如这样就是一个符合条件的数.
个人感想:
我感觉我已经很久没做过数位DP的题了.我做这题的时候居然一点感觉都没.好吧.具体我是参照转载(虽然什么都没看懂,我直接硬刚了一下就明白了)
dp[pos][p1][p2][p3][p4]代表:当前数位pos下,前4个数分别是p4,p3,p2,p1.其中pi=10代表前面没有数字
![](http://img.blog.csdn.net/20160804100220500)
首先代码的想法是枚举每一个数位, 假设当前我现在枚举【50-12345】,那么就可以通过
【0-12345】符合的个数-【0-50】符合的个数 就是我们要的答案
口口口口口 首先我们检测每一位,用最基础的数位dp思想,
0 口口口口 第一个位置填写前导0.
0 0 口口口 同样.
0 0 0 口口
0 0 0 0 口
0 0 0 0 0
0 0 0 0 1 .
0 0 0 0 2
….
1 2 3 4 5
就是一种暴力的想法,这样肯定超时,我们可以通过记忆化,因为如果我们只有有些数位是重复计算的,我们记录 它之前的4位,我们就可以知道后面有多少个数符合了.这样就不麻烦了. 用这个想法去看看代码,就很容易懂.
我做的时候会有一个疑问在flag中,flag有什么用呢?flag用来指示当前这个数是不是开始需要枚举. 可能说的太恶心了.. 就是 flag?dig[pos]:9; 如果flag=true.我只能枚举属于它的正常范围,例如pos=1,那么 12345,的万位 1,只能从【0->1】开始枚举.就是这样意思, 记忆化必须在当前不是flag=false的时候记忆.
嗯差不多了,再看看代码去意会一下应该就明白了.
分析:数位DP
代码:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5787
题意:
给你一个区间的【L,R】的数字,然后给你一个K,求要使连续K位都不会重复的数字的个数.
例如这样就是一个符合条件的数.
个人感想:
我感觉我已经很久没做过数位DP的题了.我做这题的时候居然一点感觉都没.好吧.具体我是参照转载(虽然什么都没看懂,我直接硬刚了一下就明白了)
dp[pos][p1][p2][p3][p4]代表:当前数位pos下,前4个数分别是p4,p3,p2,p1.其中pi=10代表前面没有数字
首先代码的想法是枚举每一个数位, 假设当前我现在枚举【50-12345】,那么就可以通过
【0-12345】符合的个数-【0-50】符合的个数 就是我们要的答案
口口口口口 首先我们检测每一位,用最基础的数位dp思想,
0 口口口口 第一个位置填写前导0.
0 0 口口口 同样.
0 0 0 口口
0 0 0 0 口
0 0 0 0 0
0 0 0 0 1 .
0 0 0 0 2
….
1 2 3 4 5
就是一种暴力的想法,这样肯定超时,我们可以通过记忆化,因为如果我们只有有些数位是重复计算的,我们记录 它之前的4位,我们就可以知道后面有多少个数符合了.这样就不麻烦了. 用这个想法去看看代码,就很容易懂.
我做的时候会有一个疑问在flag中,flag有什么用呢?flag用来指示当前这个数是不是开始需要枚举. 可能说的太恶心了.. 就是 flag?dig[pos]:9; 如果flag=true.我只能枚举属于它的正常范围,例如pos=1,那么 12345,的万位 1,只能从【0->1】开始枚举.就是这样意思, 记忆化必须在当前不是flag=false的时候记忆.
嗯差不多了,再看看代码去意会一下应该就明白了.
分析:数位DP
代码:
/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * */ //#define OUT #include <iostream> using namespace std; #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <sstream> #include <cctype> #include <vector> #include <set> #include <cstdlib> #include <map> #include <queue> //#include<initializer_list> //#include <windows.h> //#include <fstream> //#include <conio.h> #define MaxN 0x7fffffff #define MinN -0x7fffffff #define Clear(x) memset(x,0,sizeof(x)) typedef long long ll; const int INF=0x3f3f3f3f; ll L,R; ll K; ll top; ll dig[20]; ll dp[20][11][11][11][11]; bool check(ll p1,ll p2,ll p3,ll p4,ll now) { if(K==2) return now!=p4; if(K==3) return now!=p4&&now!=p3; if(K==4) return now!=p4&&now!=p3&&now!=p2; return now!=p4&&now!=p3&&now!=p2&&now!=p1; } ll dfs(ll pos,ll p1,ll p2,ll p3,ll p4,bool flag) { if(pos==0) return p4!=10;//前面的第一个数已经确定了,那么就不需要枚举了. if(!flag&&dp[pos][p1][p2][p3][p4]!=-1) return dp[pos][p1][p2][p3][p4]; ll Ed=flag?dig[pos]:9; ll ans=0; for(ll i=0;i<=Ed;i++) { if( i==0&& p4==10 ) ans+=dfs(pos-1,10,10,10,10,flag&&i==Ed); else if( check(p1,p2,p3,p4,i) ) ans+=dfs(pos-1,p2,p3,p4,i,flag&&i==Ed); } if(!flag) dp[pos][p1][p2][p3][p4]=ans; return ans; } ll solve(ll n) { if(n<=0)return 0; top=0; while(n) { dig[++top]=n%10; n/=10; } return dfs(top,10,10,10,10,true); } int main() { #ifdef OUT freopen("coco.txt","r",stdin); freopen("lala.txt","w",stdout); #endif while(scanf("%I64d %I64d %I64d",&L,&R,&K)!=EOF) { memset(dp,-1,sizeof(dp)); printf("%I64d\n",solve(R)-solve(L-1)); } return 0; }
相关文章推荐
- HDU 5787 K-wolf Number
- HDU 5787 K-wolf Number
- HDU 5787 wolf Number 数位dp
- HDU 5787 K-wolf Number(数位DP)
- HDU 5787 K-wolf Number 数位dp
- HDU - 5787 K-wolf Number 数位dp
- HDU 5787 K-wolf Number
- Hdu-5787 K-wolf Number(数位DP)
- HDU 5787 K-wolf Number(数位DP)
- HDU 5787 K-wolf Number (数位DP)
- 【HDU 5787】K-wolf Number(数位DP)
- HDU 5787 K-wolf Number 数位dp
- hdu 5787 K-wolf Number(数位dp)
- HDU 5787 K-wolf Number (数位DP)
- HDU 5787 K-wolf Number(数位DP)
- HDU 5787 K-wolf Number
- HDU - 5787 K-wolf Number 数位DP
- HDU 5787 K-wolf Number
- hdu-5787-K-wolf Number-数位DP
- HDU 5787 K-wolf Number(数位dp)