HDU 3555 数位DP入门(两种思路)
2017-01-24 21:37
267 查看
Bomb
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 16813 Accepted Submission(s): 6161
Problem Description
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would
add one point.
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?
Input
The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.
The input terminates by end of file marker.
Output
For each test case, output an integer indicating the final points of the power.
Sample Input
3
1
50
500
Sample Output
0
1
15
HintFrom 1 to 500, the numbers that include the sub-sequence "49" are "49","149","249","349","449","490","491","492","493","494","495","496","497","498","499",
so the answer is 15.
简单的数位DP入门题,具体分析方法可参加我的上一篇博文。 博客链接
下面是两种思路的代码:
#include <bits/stdc++.h>
using namespace std;
__int64 dp[15][3];
//dp[i][0] 合法数
//dp[i][1] 9开头的合法数
//dp[i][2] 含49的非法数
void init(void){
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
int i;
for(i=1 ;i<15 ;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];
}
}
__int64 solve(__int64 x){
int len = 0,digit[21];
while(x){
digit[++len] = x % 10;
x /= 10;
}
digit[len+1] = 0;
int i;
__int64 ans = 0;
bool flag = false;
for(i=len ;i>0 ;i--){
ans += digit[i] * dp[i-1][2];
if(flag)
ans += dp[i-1][0] * digit[i];
if(!flag && digit[i] > 4)
ans += dp[i-1][1];
if(digit[i+1] == 4 && digit[i] == 9)
flag = true;
}
return ans;
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
__int64 n;
scanf("%I64d",&n);
printf("%I64d\n",solve(n+1));
}
return 0;
}
二:
#include <bits/stdc++.h> using namespace std; __int64 dp[21][10]; void init(void){ memset(dp,0,sizeof(dp)); dp[0][0] = 1; int i,j,k; for(i=1 ;i<21 ;i++){ for(j=0 ;j<10 ;j++){ for(k=0 ;k<10 ;k++){ if(!(j==4 && k==9)) dp[i][j] += dp[i-1][k]; } } } } __int64 solve(__int64 x){ __int64 tem = x; int len = 0,digit[21]; while(x){ digit[++len] = x % 10; x /= 10; } digit[len+1] = 0; int i,j; __int64 ans = 0; for(i=len ;i>0 ;i--){ for(j=0 ;j<digit[i] ;j++){ if(!(digit[i+1] == 4 && j == 9)){ ans += dp[i][j]; } } if(digit[i+1] == 4 && digit[i] == 9) break; } return tem - ans; } int main(){ init(); int T; scanf("%d",&T); while(T--){ __int64 n; scanf("%I64d",&n); printf("%I64d\n",solve(n+1)); } return 0; }
相关文章推荐
- hdu 3555 Bomb 炸弹(数位DP,入门)
- hdu 3555 Bomb (数位dp入门)
- HDU-3555 Bomb (数位dp 入门题)
- hdu 3555(数位dp 入门)
- 数位DP入门之hdu 3555 Bomb
- HDU 3555 数位DP 入门
- HDU 3555 数位dp入门
- HDU 3555 Bomb 数位DP 入门
- hdu 3555(数位dp入门)
- 数位DP入门题 hdu 2089 hdu 3555
- HDU 3555 Bomb + HDU 2089 不要62 数位dp入门题目
- HDU 3555 Bomb 详解(数位DP入门题)
- HDU 3555 Bomb(数位DP模板啊两种形式)
- HDU3555——Bomb(数位dp入门)
- HDU 3555 Bomb(数位DP模板啊两种形式)
- 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题
- hdu---(3555)Bomb(数位dp(入门))
- hdu 3555 Bomb(数位DP,4级)
- HDU-3555 Bomb 数位DP
- 几个基础数位DP(hdu 2089,hdu 3555,uestc 1307 windy 数)