程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 3555 數位DP

HDU 3555 數位DP

編輯:C++入門知識

Bomb

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 6471    Accepted Submission(s): 2250


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

Hint
From 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。。。動態規劃真強大,前輩們的思想讓我歎服。。由衷的說:佩服!!!

對於這樣一類問題:在某個數字區間內求滿足條件或不滿足條件的數字的個數。 如果問題的數字范圍太大的話,一般來說就是數位DP。

數位DP,我的理解就是 假設求的是n---0之間的滿足條件的數字的個數,假設n=4891,那麼可以這樣算:

1)求出3999---0的滿足條件數字的個數。

2)求出4799---4000的滿足條件數字的個數。

3)求出4889---4800的滿足條件數字的個數。

4)求出4891---4890的滿足條件數字的個數。

以上加起來就是本題答案。

那麼怎麼DP呢?  有這樣一種思想,如果知道0--k位數字中滿足條件的個數num,那麼0--k+1位數字中滿足條件的個數num1=num*10;因為第k+1位有0--9   10中情況。

以上基本上就是數位dp的思想了。下面解這道題:

題意:給一個數字n,求出0---n之間含有49的數字的個數。

設dp[i][0],dp[i][1],dp[i][2]分別為從0到i位數字之間不含49數字個數,不含49但是最高位(第i位)數字為9的數字的個數,含49的數字的個數。

那麼有  dp[i][0]=dp[i-1][0]*10-dp[i-1][1];  //第i位數字可能是4,所以減去i-1位到0中最高位是9的個數。

          dp[i][1]=dp[i-1][0];

          dp[i][2]=dp[i-1][2]*10+dp[i-1][1];  //第i位數字可能是4,所以加上i-1位到0中最高位是9的個數。

 

以上就是主要思想,寫本題需要注意細節,詳見代碼:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <iostream>
 5 using namespace std;
 6 
 7 main()
 8 {
 9     __int64 n, dp[33][4], ans;
10     int t, i, j, k, bit[33];
11     memset(dp,0,sizeof(dp));
12     dp[0][0]=1;
13     for(i=1;i<=20;i++)                             //dp過程 
14     {
15         dp[i][0]=dp[i-1][0]*10-dp[i-1][1];
16         dp[i][1]=dp[i-1][0];
17         dp[i][2]=dp[i-1][2]*10+dp[i-1][1];
18     }
19     scanf("%d",&t);
20     while(t--)
21     {
22         scanf("%I64d",&n);
23         k=0;
24         n++;                             //因為該程序求的是[0,n)半開半閉區間的個數,以防數字n滿足條件,所以n+1 
25         while(n)                                 //把n每位數字放進一個數組裡 
26         {
27             bit[++k]=n%10;
28             n/=10;
29         }
30         ans=0;
31         bit[k+1]=0;
32         int flag=0;
33         for(i=k;i>=1;i--)                      //求解過程 
34         {
35             ans+=dp[i-1][2]*bit[i];
36             if(flag) ans+=dp[i-1][0]*bit[i];            //如果高位數字中含有49 那麼以後不管是什麼數字都滿足條件 
37             if(!flag&&bit[i]>4) ans+=dp[i-1][1];         //如果高位數字鐘不含49 但是第i位大於4,那麼需要加上第i位是4,第i+1位是9的數字 
38             if(bit[i+1]==4&&bit[i]==9) flag=1;
39         }
40         printf("%I64d\n",ans);
41     }
42 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved