日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【bzoj5064】B-number 数位dp

發(fā)布時間:2024/1/17 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【bzoj5064】B-number 数位dp 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目描述

B數(shù)的定義:能被13整除且本身包含字符串"13"的數(shù)。 例如:130和2613是B數(shù),但是143和2639不是B數(shù)。 你的任務(wù)是計算1到n之間有多少個數(shù)是B數(shù)。

輸入

輸入數(shù)據(jù)只有一個數(shù),為n。(1<=N<=10^15)

輸出

輸出數(shù)據(jù)包含一行,為1到n之間B數(shù)的個數(shù)。

樣例輸入

13

樣例輸出

1


題解

數(shù)位dp

由于要求被13整除,因此要記錄對13的模數(shù)。

由于要包含字符串"13",因此要記錄是否出現(xiàn)過字符串"13",同時還要記錄首位是什么以便轉(zhuǎn)移。

于是設(shè) $f[i][j][k][0/1]$ 表示 $i$ 位數(shù),對13取模的結(jié)果為 $j$ ,首位為 $k$ ,是否包含字符串"13"的數(shù)的個數(shù)。

直接預(yù)處理出 $f$ 數(shù)組以及 $10^k$ ,然后數(shù)位dp求解即可。

首先算出不滿總位數(shù)的答案,然后考慮滿位數(shù)的,那么如果dp的當前位小于原數(shù)的當前位則直接計算答案,否則留到下一步處理。這里最好把所求區(qū)間轉(zhuǎn)化為 $[1,n+1)$ 的半開半閉區(qū)間來求。

細節(jié)還算比較少的啦

#include <cstdio> typedef long long ll; ll b[17] , f[17][13][10][2]; int main() {int i , j , k , l , m , di = 1 , flag = 0;ll n , now = 0 , ans = 0;b[0] = f[0][0][0][0] = 1;for(i = 1 ; i <= 16 ; i ++ ){b[i] = b[i - 1] * 10;for(j = 0 ; j < 13 ; j ++ )for(k = 0 ; k < 10 ; k ++ )for(l = 0 ; l < 10 ; l ++ )for(m = 0 ; m < 2 ; m ++ )f[i][(j + k * b[i - 1]) % 13][k][m || (k == 1 && l == 3)] += f[i - 1][j][l][m];}scanf("%lld" , &n) , n ++ ;for(i = 1 ; b[i] <= n ; i ++ )for(j = 1 ; j < 10 ; j ++ )ans += f[i][0][j][1];for( ; i ; i -- ){for(j = di ; j < n / b[i - 1] % 10 ; j ++ )ans += f[i][(13 - now * b[i] % 13) % 13][j][1] + (flag || (n / b[i] % 10 == 1 && j == 3)) * f[i][(13 - now * b[i] % 13) % 13][j][0];now = (now * 10 + n / b[i - 1] % 10) % 13 , di = 0;if(n / b[i] % 10 == 1 && n / b[i - 1] % 10 == 3) flag = 1;}printf("%lld\n" , ans);return 0; }

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/GXZlegend/p/7808062.html

總結(jié)

以上是生活随笔為你收集整理的【bzoj5064】B-number 数位dp的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。