题目链接:HDU 3555 Bomb
数位dp。
这个题有三种状态,0表示前一位不是4并且前几位没有49,1表示前一位是4并且前几位没有49,2表示前几位有49。
剩下的全写在注释上了。
#include <iostream>
#include <cstring>
using namespace std;
const int MAX_N = 20 + 5;
long long dp[MAX_N][3];
long long num[MAX_N];
long long n;
int T;
long long f(int pos, int st, bool limit)
{
if(pos == -1)
return st == 2;
if(!limit && dp[pos][st] != -1)
return dp[pos][st];
long long ans = 0;
int last = limit ? num[pos] : 9;
for(int i = 0; i <= last; i++)
{
int temp = st;//开始没这么写,返回值一直是0。。。
if(st == 1 && i == 9)//前一位是4,这一位是9
temp = 2;
else if(st == 1 && i != 4)//前一位是4,这一位不是4
temp = 0;
else if(i == 4 && st != 2)//这一位是4并且前边不包括49,即st != 2
temp = 1;
ans += f(pos - 1, temp, limit && i == last);
}
if(!limit)
dp[pos][st] = ans;
return ans;
}
long long cal(long long n)
{
int pos = 0;
while(n > 0)
{
num[pos] = n % 10;
n /= 10;
pos++;
}
return f(pos - 1, 0, 1);
}
int main()
{
cin >> T;
memset(dp, -1, sizeof(dp));
while(T--)
{
cin >> n;
cout << cal(n) << endl;
}
return 0;
}
本文详细解析了HDU3555 Bomb问题的数位DP解决方案,介绍了状态划分及转移过程。该问题涉及三种状态:0表示前一位不是4且前几位没有49;1表示前一位是4且前几位没有49;2表示前几位有49。通过递归函数实现状态转移,最终求得符合特定条件的数字数量。
489

被折叠的 条评论
为什么被折叠?



