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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【hdu3555】Bomb 数位dp

發布時間:2025/7/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【hdu3555】Bomb 数位dp 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

求 1~N 內包含數位串 “49” 的數的個數。

輸入

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.

輸出

For each test case, output an integer indicating the final points of the power.

樣例輸入

3
1
50
500

樣例輸出

0
1
15?


?

題解

數位dp

設 $f[i][j][0/1]$ 表示 $i$ 位數,最高位為 $j$ ,是否包含數位串 “49” 的數的個數。

首先預處理出 $f$ 數組,根據是否以前有“49”或能構成“49”來更新新的 $f$ 值。

然后對于每個詢問跑數位dp:先計算位數不滿 $n$ 的位數的數的答案,然后從高位到低位計算,統計該位小于該數當前位的的數,相等的位考慮下一位。

注意統計當前位時需要同時考慮前面是否有“49”,兩個數位能否拼成“49”,后面是否有“49”。然而本題數字串的第二位是“9”,枚舉時枚舉不到9,因此不需要考慮前后兩個數位拼成“49”的情況。

把詢問轉化為 $[1,n)$ 的區間會更容易些。

代碼中為了避免一些細節(比如 $10^{19}$ 爆long long之類的),使用了unsigned long long。

#include <cstdio> typedef unsigned long long ull; ull f[20][10][2] , b[20]; void init() {int i , j , k , l;f[0][0][0] = b[0] = 1;for(i = 1 ; i < 20 ; i ++ ){b[i] = b[i - 1] * 10;for(j = 0 ; j < 10 ; j ++ )for(k = 0 ; k < 10 ; k ++ )for(l = 0 ; l < 2 ; l ++ )f[i][j][l || (j == 4 && k == 9)] += f[i - 1][k][l];} } ull calc(ull n) {int i , j , di = 1 , flag = 0 , last = 0 , now;ull ans = 0;for(i = 1 ; b[i] <= n ; i ++ )for(j = 1 ; j < 10 ; j ++ )ans += f[i][j][1];for( ; i ; i -- ){now = n / b[i - 1] % 10;for(j = di ; j < now ; j ++ )ans += f[i][j][1] + f[i][j][0] * flag;if(last == 4 && now == 9) flag = 1;di = 0 , last = now;}return ans; } int main() {init();int T;ull n;scanf("%d" , &T);while(T -- ) scanf("%llu" , &n) , printf("%llu\n" , calc(n + 1));return 0; }

?

轉載于:https://www.cnblogs.com/GXZlegend/p/7812831.html

總結

以上是生活随笔為你收集整理的【hdu3555】Bomb 数位dp的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。