HDU2089 数位DP

来源:互联网 发布:python 绘制中国地图 编辑:程序博客网 时间:2024/06/05 15:15

    原问题是求区间 [ n, m ]中,不含数字4和62的数的总个数.采用的办法是数位 DP。定义数组 dp[i][2],他的含义如下:

 dp[i][0] : 表示数字最大长度是 i 且不含4和62的数总个数。

 dp[i][1] : 表示数字的最大长度是 i 且不含 4 和62,但是最高位是2的数总个数。

于是:dp[i][0]=dp[i-1][0]*9-dp[i-1][1];

           dp[i][1]=dp[i-1][0];

计算 dp[i][2]代码如下:

memset(dp, 0, sizeof(dp));dp[0][0] =1;for (i = 1; i <10; i++){dp[i][0] = dp[i - 1][0] * 9 - dp[i - 1][1];dp[i][1] = dp[i - 1][0];}

完成 了上一步。我们将区间 [n,m]分为两部分来计算:即是计算[0,n]和[0,m],然后相减来的到最后结果(端点需要特殊处理)。同样的将数字 x分区间统计,如 x =598,则分为:

     5:  0 - 499

     9:  500-589

     8:  590-597

然后还有598本身。

注意一种情况,如果数字 x本身含有62或者4,则62或者4后面就没有满足要求的数字了。比如x=584169.则584后面的就没有满足要求的数字了。

#include<iostream>using namespace std;int dp[10][2];int bit[12];int Compute(int x,bool &flag);int main(){int i, n, m,ans;bool flag;memset(dp, 0, sizeof(dp));dp[0][0] =1;for (i = 1; i <10; i++){dp[i][0] = dp[i - 1][0] * 9 - dp[i - 1][1];dp[i][1] = dp[i - 1][0];}while (1){scanf("%d%d", &n, &m);if (n==0&&m==0)break;flag = 0;ans = Compute(m, flag);flag = 0;ans -= Compute(n,flag);if (!flag)ans++;printf("%d\n", ans);}return 0;}int Compute(int x,bool &flag){int i, len, ans;len = ans = 0;while (x){bit[++len] = x % 10;x /= 10;}bit[len + 1] = 0;//-------------------------------------------------------for (i = len; i > 0; i--){if (flag)  //原数字出现了4或者62break;if (bit[i + 1] == 6 && bit[i] > 2) //上一位是6时本位不可选择2ans -= dp[i][1];if (bit[i] > 6)ans -= dp[i - 1][1];   //本位大于6时,当本位选择6 ,下一位选择2的都要减去if (bit[i] > 4)ans += (bit[i] - 1)*dp[i - 1][0];    //大于4的时候本位是不可以选择4的if (bit[i] <= 4)ans += bit[i] * dp[i - 1][0];if (bit[i] == 4||(bit[i + 1] ==6 && bit[i] == 2))  //判断是否出现4或者62flag = true;}if (!flag)    //判断原数字是否符合要求ans++;           return ans;}


 

0 0
原创粉丝点击