标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 11029 Accepted Submission(s): 3916
/** 题意:1~n之间有多少数包含49 做法:数位dp ///dp[i][0] 表示当前位没有49 ///dp[i][1] 表示当前位是以9开头 ///dp[i][2] 表示含有49 设sum = 0; 对于n进行从高到低进行的扫描 对于当前位 sum += dp[i-1][2]*mmap[i] 对于i-1满足要求的 如果当前的位数 > 4 并且没有包含49 那么 sum += dp[i-1][1]; 如果当前已经有49了 那么 sum += dp[i-1][0] * mmap[i]; **/ #include<iostream> #include<cstring> #include<cstdio> using namespace std; long long dp[20][3]; int digit[20]; ///dp[i][0] 表示当前位没有49 ///dp[i][1] 表示当前位是以9开头 ///dp[i][2] 表示含有49 int main() { memset(dp, 0, sizeof(dp)); dp[0][0] = 1; 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]; } int t; cin >> t; while(t--) { int len = 0, last = 0; long long ans = 0; unsigned long long n = 0; cin >> n; n++; memset(digit, 0, sizeof(digit)); while(n) { digit[++len] = n % 10; n /= 10; } bool flag = false; for(int i = len; i >= 1; i--) { ans += dp[i - 1][2] * digit[i]; ///当前位的可能 if(flag) { ans += dp[i - 1][0] * digit[i]; ///如果已经含有49 加上I-1个不符合要求的个数 } if(!flag && digit[i] > 4) //当前位 > 4 以为前一位已经是9了所以包含49 { ans += dp[i - 1][1]; } if(last == 4 && digit[i] == 9) ///包含49 { flag = true; } last = digit[i]; ///标记上一位 } cout << ans << endl; } return 0; }
标签:
原文地址:http://www.cnblogs.com/chenyang920/p/4802457.html