HDU3652 B-number 数位DP

来源:互联网 发布:打水软件是什么 编辑:程序博客网 时间:2024/05/20 10:11
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.
Input
Process till EOF. In each line, there is one positive integer n(1 <= n <= 1000000000).
Output
Print each answer in a single line.
Sample Input
131002001000
Sample Output

1122


题意:求既能被13整除,并且有13字串的数字。
思路:将mark表示状态,mark == 1 表示 无13且有1,  mark == 2 表示有13,mark == 0 表示无13且没有1。然后再用sta表示是否能够被13整除即可。
Code:
#include <iostream>#include <cstdio>#include <string.h>#define LL long longusing namespace std;const int MOD = 1e9+7;int a[25];LL dp[25][25][3];LL dfs( int pos , int sta , int mark , bool limit ){if( pos == -1 ) return mark == 2 && sta == 0 ;if( !limit && dp[pos][sta][mark] != -1 ) return dp[pos][sta][mark];LL ans = 0 ;int up = limit ? a[pos] : 9 ;for( int i = 0 ; i <= up ; i ++ ){int temp = ( sta * 10 + i ) % 13;int tmp = mark;if( mark == 0 && i == 1 ) tmp = 1;if( mark == 1 && i != 1 ) tmp = 0;if( mark == 1 && i == 3 ) tmp = 2; ans += dfs( pos - 1 , temp , tmp , limit && i == up ) ;}if( !limit )  dp[pos][sta][mark] = ans ;return ans ;}LL solve( LL x ){int tot = 0 ;while( x ){a[tot++] = x % 10 ;x /= 10;}return dfs( tot - 1 , 0 , 0 , true );}int main(){//ios_base::sync_with_stdio(false); cin.tie(0);memset(dp,-1,sizeof(dp));LL n;while(~scanf("%lld",&n))printf("%lld\n",solve(n));return 0;}