fzu 2109 Mountain Number 数位DP 记忆化搜索
2013-02-28 21:39
489 查看
做法:按位暴力DFS吧...
这里很明显没有考虑当前数字是否是首位,其实不需要啊,因为这种情况发生的时候肯定是那种比边界数少一位的数字。也就是说如果求1234 那么这里要考虑的是 0 ---999的
数字中的mountain, 没有考虑首位的后果是moutain的形态不同,可是很容易证明,规定位数的数字只有两种moutain,而这种两种moutain在 0---999中的个数相同。
这里很明显没有考虑当前数字是否是首位,其实不需要啊,因为这种情况发生的时候肯定是那种比边界数少一位的数字。也就是说如果求1234 那么这里要考虑的是 0 ---999的
数字中的mountain, 没有考虑首位的后果是moutain的形态不同,可是很容易证明,规定位数的数字只有两种moutain,而这种两种moutain在 0---999中的个数相同。
#include <iostream> #include <cstdio> #include <cstring> #define LL long long const int LMT=11; using namespace std; LL dp[LMT][LMT][LMT]; int sec[LMT]; LL dfs(int pre,int pos,int len,bool tag) { if(dp[pre][pos][len]!=-1&&(!tag||pos==len))return dp[pre][pos][len]; LL res=0; int end=tag?sec[pos]:9; if(pos&1) { for(int j=end;j>=pre;j--) res+=dfs(j,pos+1,len,tag&&j==end); } else { for(int j=min(end,pre);j>=0;j--) res+=dfs(j,pos+1,len,tag&&j==end); } if(!tag)dp[pre][pos][len]=res; return res; } int work(LL x) { int num[LMT],res=0; do { num[res]=x%10; res++; } while(x/=10); for(int i=0,j=res-1;j>=0;j--,i++) sec[i]=num[j]; return res; } int main(void) { int T; scanf("%d",&T); memset(dp,-1,sizeof(dp)); for(int i=0;i<LMT;i++) for(int j=0;j<LMT;j++) dp[i][j][j]=1; while(T--) { LL a,b,x,y; scanf("%I64d%I64d",&a,&b); x=dfs(9,0,work(a-1),1); y=dfs(9,0,work(b),1); printf("%I64d\n",y-x); } return 0; }
相关文章推荐
- fzu 2109 Mountain Number 数位DP
- fzu 2109 Mountain Number 数位DP 递推
- fzu2109--Mountain Number(数位dp)
- FZU 2109 Mountain Number_数位DP
- FZU-2109 Mountain Number(数位dp)
- FZU 2109 Mountain Number (数位DP)
- FZU 2109 Mountain Number [数位DP]【动态规划】
- FZU - 2109 Mountain Number 数位DP
- fzu 2109(数位dp)
- fzu Problem 2113 Jason的特殊爱好 (数位dp)
- HDU3652_B-number_数位DP&记忆化搜索
- 【HDU3555】Bomb【数位DP】【记忆化搜索】
- FZU2109:Mountain Number(数位DP)
- hdu_3562_B-number(记忆化搜索|数位DP)
- HDU 3652 B-number(数位dp&记忆化搜索)
- hdu-3943[数位dp(记忆化搜索)+二分]
- 【HDU2089】不要62【数位DP】【记忆化搜索】
- hdu_3562_B-number(记忆化搜索|数位DP)
- 数位DP与记忆化搜索-HDU3652
- 链接前导fzu 2109 Mountain Number