HDU2089 不要62[数位DP]

来源:互联网 发布:赌球外围软件 编辑:程序博客网 时间:2024/06/06 01:05

      A - 不要62

 HDU - 2089 




                
          
题解:

统计[n,m]中不含4 或者 62的数有多少个,首先判断有4就直接continue,当前函数记录前一位数字为多少,如果前一位为6且当前位为2也是不符合的,也是直接continue。所以我们只要知道不大于m能构造出多少个这样的数和不大于n-1(因为统计中包括了n)能构造出多少个,用sum(m)-sum(n-1)就可以求出这个[n,m]中存在多少个符合条件的数了。

状态转移的话,dp[i][j] 第一维表示当前位置,第二维表示状态,仅有两种状态,0表示前一位不是6,1表示前一位是6。



#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<string>#include<algorithm>#include<queue>#include<stack>#include<set>#include<map>#include<vector>using namespace std;typedef long long ll;const int N=20;int num[N];ll dp[N][2];ll dfs(int pos,int pre,int sta,bool limit){if (pos==-1)return 1;if (!limit && dp[pos][sta]!=-1)return dp[pos][sta];int up=limit?num[pos]:9;ll cnt=0;for (int i=0 ; i<=up ; ++i){if (i==4 || (pre==6 && i==2))continue;cnt+=dfs(pos-1,i,i==6,limit && i==num[pos]);}if (!limit)dp[pos][sta]=cnt;return cnt;}ll divi(int n){int pos=0;while (n){num[pos++]=n%10;n/=10;}return dfs(pos-1,-1,0,1);}int main(){int n,m;memset(dp,-1,sizeof(dp));while (~scanf("%d%d",&n,&m) && (n+m)){ printf("%lld\n",divi(m)-divi(n-1));}return 0;}



原创粉丝点击