HDU 2089 不要62(数位DP)

来源:互联网 发布:单片机驱动程序 编辑:程序博客网 时间:2024/06/05 01:45

题目链接:点击打开链接

题意:中文题目,很显然

思路:数位DP入门,DP函数有四个参量,当前位置,前一位的数字,前一位是否为6,前几位取值是否都是上限。dp[i][state]表示第i位在limit(limit对应第四个参量)取0时,该state状态下(state对应第三个参量)剩余位数(包括本位)取值满足条件的方案和。

// HDU 2089 不要62.cpp 运行/限制:0ms/1000ms#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;int dp[10][2];int upper, dig[10];int DP(int pos, int pre, int state, int limit) {//位置 前一位的数字 前一位是否为6 前几位是否是上限if (pos == -1) {return 1;}if (!limit && dp[pos][state] != -1) {return dp[pos][state];}int re = 0;int top = limit ? dig[pos] : 9;for (int i = 0; i <= top; i++) {if (i == 4) continue;if (pre == 6 && i == 2) continue;re += DP(pos - 1, i, i == 6, limit && i == dig[pos]);}if (!limit) dp[pos][state] = re;return re;}int solve(int num) {upper = 0;while (num) {dig[upper++] = num % 10;num /= 10;}return DP(upper - 1, -1, 0, 1);}int main(){int n, m;memset(dp, -1, sizeof(dp));//优化:dp数组在此初始化,能节省很多时间,因为在limit取0时,dp数组的取值只和数位有关,和测试数据的范围无关while (scanf("%d%d", &n, &m) != EOF && n && m) {printf("%d\n", solve(m) - solve(n - 1));}    return 0;}


原创粉丝点击