hdu 3555 数位DP

烂漫一生 提交于 2020-02-28 12:03:56

这题完全是看解题报告做出来的,之前完全没有这样的思路, DP数组的含义还是挺好理解的,后面使用的时候反而是想了好久才理解……

/* * hdu3555/linux.cpp * Created on: 2011-8-30 * Author    : ben */#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>using namespace std;typedef long long I64;typedef unsigned long long U64;/* * dp[i][0]表示长度为i,不包含49的数字的个数 * dp[i][1]表示长度为i,不包含49但以9开头的数字的个数 * dp[i][2]表示长度为i,包含49的数字的个数 */U64 dp[21][3];char digit[25];void work();int main() {#ifndef ONLINE_JUDGE    freopen("data.in", "r", stdin);#endif    work();    return 0;}void init() {    dp[0][0] = 1;    dp[0][1] = 0;    dp[0][2] = 0;    for(int i = 1; i < 20; i++) {        dp[i][0] = dp[i - 1][0] * 10 - dp[i - 1][1];        dp[i][1] = dp[i - 1][0];        dp[i][2] = dp[i - 1][2] * 10 + dp[i - 1][1];    }}void work() {    int T, len;    U64 N, ans;    bool flag;    init();    scanf("%d", &T);    while(T--) {        scanf("%I64u", &N);        N++;//加1便于处理形如..49的数        sprintf(digit, "%I64d", N);        len = strlen(digit);        ans = 0;        flag = false;        for(int i = len; i > 0; i--) {            ans += dp[i - 1][2] * (digit[len - i] - '0');            if(flag) {                ans += dp[i - 1][0] * (digit[len - i] - '0');            }else {                if(digit[len - i] > '4') {                    ans += dp[i - 1][1];                }            }            if(i < len && digit[len - i - 1] == '4' && digit[len - i] == '9') {                flag = true;            }        }        printf("%I64u\n", ans);    }}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!