2017广东工业大学程序设计竞赛决赛 Problem G: 等凹数字(回文+数位dp)
2017-03-29 18:27
399 查看
Problem G: 等凹数字
Description
定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如543212345,5544334455是合法的等凹数字,543212346,123321,111111不是等凹数字。现在问你[L,R]中有多少等凹数字呢?
Input
第一行一个整数T,表示数据的组数。
接下来T行每行俩个数字L和R,(1<=L<=R<=1e18)
Output
输出一个整数,代表[L,R]中有多少等凹数字
Sample Input
2
1 100
101 200
Sample Output
0
1
HINT
小于等于2位的数字无凹峰
套上回文数位dp模板,加上4个维度(上升,下降,前导0,前一个数)看了一下别人解题思路,知道多开这几维才写出来QAQ
代码里有自己的注释
AC代码
Description
定义一种数字称为等凹数字,即从高位到地位,每一位的数字先非递增再非递减,不能全部数字一样,且该数是一个回文数,即从左读到右与从右读到左是一样的,仅形成一个等凹峰,如543212345,5544334455是合法的等凹数字,543212346,123321,111111不是等凹数字。现在问你[L,R]中有多少等凹数字呢?
Input
第一行一个整数T,表示数据的组数。
接下来T行每行俩个数字L和R,(1<=L<=R<=1e18)
Output
输出一个整数,代表[L,R]中有多少等凹数字
Sample Input
2
1 100
101 200
Sample Output
0
1
HINT
小于等于2位的数字无凹峰
套上回文数位dp模板,加上4个维度(上升,下降,前导0,前一个数)看了一下别人解题思路,知道多开这几维才写出来QAQ
代码里有自己的注释
AC代码
#include<stdio.h> #include<string.h> int degth[20]; int temp[20]; long long dp[20][20][10][3][3][3]; long long dfs(int pos,int len,int pre,int up,int down,int flag,int f,int k)//长度,当前位,前一位,上升,下降,回文 { if(len<0) return up&&down&&flag; //上升加下降加是回文 if(!f&&dp[pos][len][pre][up][down][flag]!=-1&&!k) return dp[pos][len][pre][up][down][flag]; int max=f?degth[len]:9; long long ret=0; for(int i=0;i<=max;i++) { temp[len]=i; if(k) //前导0时直接降低长度,否则执行下一位(因为起始位无法判断上升和下降) ret+=dfs(pos-(k&&i==0),len-1,i,0,0,flag,f&&i==max,k&&i==0); else if(pre==i) { if(flag&&(pos+1)/2>len) ret+=dfs(pos,len-1,i,up,down,i==temp[pos-len],f&&i==max,k&&i==0); else ret+=dfs(pos,len-1,i,up,down,flag,f&&i==max,k&&i==0); } else if(pre<i)//递增 { if(!down) continue; //没有下降就上升 if(flag&&(pos+1)/2>len) ret+=dfs(pos,len-1,i,1,down,i==temp[pos-len],f&&i==max,k&&i==0); else ret+=dfs(pos,len-1,i,1,down,flag,f&&i==max,k&&i==0); } else if(pre>i)//递减 { if(up) continue;//已经上升过 i d682 f(flag&&(pos+1)/2>len) ret+=dfs(pos,len-1,i,up,1,i==temp[pos-len],f&&i==max,k&&i==0); else ret+=dfs(pos,len-1,i,up,1,flag,f&&i==max,k&&i==0); } } if(!f&&!k) dp[pos][len][pre][up][down][flag]=ret; return ret; } long long solve(long long x) { int len=0; while(x) { degth[len++]=x%10; x/=10; } return dfs(len-1,len-1,0,0,0,1,1,1); } int main() { memset(dp,-1,sizeof(dp)); int T; scanf("%d",&T); while(T--) { long long l,r; scanf("%lld%lld",&l,&r); printf("%lld\n",solve(r)-solve(l-1)); } }
相关文章推荐
- 2017广东工业大学程序设计竞赛决赛:G. 等凹数字(数位DP)
- 2017广东工业大学程序设计竞赛决赛 Problem B: 占点游戏(博弈)
- 2017广东工业大学程序设计竞赛决赛 Problem E: 倒水(Water)(思维)
- 2017广东工业大学程序设计竞赛决赛 Problem H: tmk买礼物(数论)
- 2017广东工业大学程序设计竞赛决赛 Problem E: 倒水(Water)(思维)
- 2017广东工业大学程序设计竞赛决赛 Problem H: tmk买礼物(数论)
- 2017广东工业大学程序设计竞赛决赛 题解&源码(A,数学解方程,B,贪心博弈,C,递归,D,水,E,贪心,面试题,F,贪心,枚举,LCA,G,dp,记忆化搜索,H,思维题)
- 2017广东工业大学程序设计竞赛决赛 Problem E: 倒水
- 2017广东工业大学程序设计竞赛决赛 Problem B: 占点游戏(博弈)
- 2017广东工业大学程序设计竞赛决赛 Problem E: 倒水(Water)(思维)
- 2017广东工业大学程序设计竞赛决赛 Problem H: tmk买礼物(数论)
- 2017广东工业大学程序设计竞赛决赛 Problem E: 倒水(Water) (详解)
- 2017广东工业大学程序设计竞赛决赛 Problem B: 占点游戏(博弈)
- 2017广东工业大学程序设计竞赛决赛 Problem E: 倒水(Water)(思维)
- 2017广东工业大学程序设计竞赛决赛 Problem H: tmk买礼物(数论)
- 2017广东工业大学程序设计竞赛决赛 Problem B: 占点游戏(博弈)
- 2017广东工业大学程序设计竞赛决赛 Problem E: 倒水(Water)(思维)
- 2017广东工业大学程序设计竞赛决赛 Problem H: tmk买礼物(数论)
- 2017广东工业大学程序设计竞赛决赛C 爬楼梯(DP)
- 2017广东工业大学程序设计竞赛决赛 Problem B: 占点游戏(博弈)