hdu 3555 - Bomb [数位dp]
2011-09-06 16:42
441 查看
/** 传说中的 “按位dp” 或 “数位dp”。 dp[len][0] 代表数字长度为len不含49的个数 dp[len][1] 代表数字长度为len不含49但是以9开头的个数(显然dp[len][1]包含在dp[len][0]中) dp[len][2] 代表数字长度为len含有49的个数 状态转移方程如代码中所示。 然后从n的高位开始统计,其中有一些细节要处理。 **/ #include<iostream> #include<cstring> #include<cstdio> using namespace std; typedef long long LL; int main() { LL dp[22][3]; int digit[22]; memset(dp, 0, sizeof(dp)); dp[0][0] = 1; for(int i=1; i<20; i++) { dp[i][0] = 10*dp[i-1][0] - dp[i-1][1]; // 在dp[i-1][0]前面添上0~9,但是要减去dp[i-1][1] 因为4和9构成49 dp[i][1] = dp[i-1][0]; // 直接在dp[i-1][0]前面添上9就行了 dp[i][2] = 10*dp[i-1][2] + dp[i-1][1]; // 在dp[i-1][2]前面添上0~9,或者在dp[i-1][1]前面添上4 } int t, len; LL n, res; cin >> t; while ( t-- ) { cin >> n; memset(digit, 0, sizeof(digit)); len = 0; while ( n ) { digit[++len] = n%10; n /= 10; } bool flag = false; res = 0; for (int i = len; i >= 1; i--) { res += dp[i-1][2]*digit[i]; if (flag) res += dp[i-1][0]*digit[i]; else if (digit[i] > 4) res += dp[i-1][1]; if (digit[i+1] == 4 && digit[i] == 9) flag = true; } if (flag) res++; // 看别人的代码都是在输入n之后就给n+1,不明白为什么,因为如果把题目中的49改成48,47...那么n+1也就不管用了, // 我没有把n+1,而是用判断flag为真时,res+1,经测试AC,是对的,道理自己想... cout << res << endl; } return 0; }
相关文章推荐
- HDU3555——Bomb(数位DP)
- HDU 3555 Bomb(数位DP)
- 动态规划晋级——HDU 3555 Bomb【数位DP详解】
- HDU-3555 Bomb 数位dp
- HDU - 3555 Bomb (数位DP)
- Bomb - HDU 3555 数位dp
- HDU 3555 Bomb (数位dp)
- HDU 3555 Bomb [数位DP]【动态规划】
- hdu 3555 Bomb 数位dp
- [数位dp] hdu 3555 Bomb
- HDU 3555 Bomb (数位DP)
- 【数位DP】【HDU 3555】Bomb
- 动态规划晋级——HDU 3555 Bomb【数位DP详解】
- HDU 3555 Bomb (数位DP)
- HDU 2089 不要62 && HDU 3555 Bomb (数位DP)
- hdu 3555 Bomb(数位dp)
- HDU 3555 Bomb ,HDU 2089 深刻学习数位dp (各种方法乱用)
- [HDU 3555] Bomb [数位DP]
- HDU-3555 Bomb (数位dp 入门题)
- 【数位dp】hud 2089 不要62 hdu 3555 Bomb