这题完全是看解题报告做出来的,之前完全没有这样的思路, 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); }}
来源:https://www.cnblogs.com/moonbay/archive/2011/08/30/2159737.html