P2657 [SCOI2009]windy数 (数位DP)

纵饮孤独 提交于 2019-12-01 11:30:09

 

题目地址


 注意点:

  • 边界讨论.

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int INF=2e9;
 7 int dp[15][15];
 8 int num[15];//每一位数字的最大值 
 9 int dfs(int len,int last,bool isMaxed,bool lead){//lead: 是否有前导零 
10     if(len==0)return 1;//递归边界 
11     if(!lead&&!isMaxed&&dp[len][last])
12         return dp[len][last];
13     int cnt=0;
14     int nowMaxVal=(isMaxed?num[len]:9);//当前位最大值 
15     for(int i=0;i<=nowMaxVal;i++){//枚举当前位数字 
16         if(abs(i-last)<2)continue; 
17         int nowNum=i;//当前位数字 
18         if(lead&&i==0)nowNum=-INF;//继续增加前导零 
19         cnt+=dfs(len-1,nowNum,(isMaxed)&&(i==nowMaxVal),(nowNum==-INF));
20     }
21     if(!lead)
22         dp[len][last]=cnt;
23     return cnt;
24 }
25 int solve(int x){
26     int nowDigit=0;//当前位数 
27     while(x){//数字分割 
28         num[++nowDigit]=x%10;
29         x/=10;
30     }
31     return dfs(nowDigit,-INF,1,1);
32 }
33 int main(){
34     int l,r;
35     scanf("%d%d",&l,&r);
36     printf("%d\n",solve(r)-solve(l-1));
37     return 0;
38 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!