您的位置:首页 > 其它

hdu3652 B-number 数位dp

2019-08-13 15:55 246 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_43279710/article/details/99441594

hdu3652

A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string “13” and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n.
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
Print each answer in a single line.

题意:给定n,求0-n满足含‘13’且可以被13整除的数的个数。
题解:数位dp。

#include <cstdio>
#include <cstring>
#pragma GCC optimize(3)
using namespace std;
typedef long long ll;

ll dp[30][135];
//第二维同时hash了前面的数模13的余数与三个状态:
//0-前面没有出现‘13’而且前一位不是1,1-前面没有出现‘13’而且前一位是1,2-前面出现‘13’

ll a[30];
//pos:位 pre:前置数 l:limit即卡不卡上界 f:flag表示前面是否出现'13'
ll dfs(int pos, ll pre, bool l, bool f){
if(pos==-1) return f && !(pre%13);
if(!l && f && dp[pos][pre%13*10] != -1) return dp[pos][pre%13*10];
if(!l && !f && pre%10 != 1 && dp[pos][pre%13*10+2] != -1) return dp[pos][pre%13*10+2];
if(!l && !f && pre%10 == 1 && dp[pos][pre%13*10+1] != -1) return dp[pos][pre%13*10+1];
int up = l ? a[pos]:9;
ll ans = 0;
for(int i = 0; i <= up; i++)
ans += dfs(pos-1, pre*10+i, l&am
7ff7
p;&i==up, f||(pre%10==1&&i==3));
if(!l){
if(f) dp[pos][pre%13*10] = ans;
if(!f && pre%10!=1) dp[pos][pre%13*10+2] = ans;
if(!f && pre%10==1) dp[pos][pre%13*10+1] = ans;
}
return ans;
}
ll solve(ll x){
int pos = 0;
while(x){
a[pos++] = x % 10;
x /= 10;
}
return dfs(pos-1, 0, true, false);
}
int main(){
memset(dp, -1, sizeof(dp));
ll x;
while(~scanf("%lld", &x)){
printf("%lld\n", solve(x));
}
}
//%lzwjymmkpwjdkslrhzxmmhyhwdjrsbtxdysfgsswttqqwzytjh
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: