【牛客-21302】被3整除的子序列(動態規划)


被3整除的子序列


題目描述

給你一個長度為50的數字串,問你有多少個子序列構成的數字可以被3整除
答案對1e9+7取模

輸入描述:

輸入一個字符串,由數字構成,長度小於等於50

輸出描述:

輸出一個整數

示例1

輸入

132

輸出

3

示例2

輸入

9

 

輸出
1
題目鏈接:
 
這題仔細想想,可以這樣寫,每個數字串都可以從第一個最后一個去考慮,設初始子序列個數為len,每增加一個數,子序列就變為2*len+1;
設dp[0],dp[1],dp[2],表示除3得到的余數分別為0,1,2。每增加一個數就更新一遍數組。
余數為0:dp[0]=dp[0]+dp[0]+1;
      dp[1]=dp[1]+dp[1];
      dp[2]=dp[2]+dp[2];
余數為1:dp[0]=dp[0]+dp[2];
      dp[1]=dp[1]+dp[0]+1;
      dp[2]=dp[2]+dp[1];
余數為2:dp[0]=dp[0]+dp[1];
      dp[1]=dp[1]+dp[2];
      dp[2]=dp[2]+dp[0]+1;
這個規律自己找幾個數測一下就有了
 
AC代碼
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <fstream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <deque>
 7 #include <vector>
 8 #include <queue>
 9 #include <string>
10 #include <cstring>
11 #include <map>
12 #include <stack>
13 #include <set>
14 using namespace std;
15 const int Mod=1e9+7;
16 char ch[1000];
17 int dp[3];
18 int f(char s)//字符串轉換整數
19 {
20     return s-'0';
21 }
22 int main()
23 {
24     cin.getline(ch,1000);
25     memset(dp,0,sizeof(dp));
26 
27     int len=strlen(ch);
28     for(int i=0; i<len; i++)//開始從第一個數遍歷
29     {
30         /*
31         重點來了,這步不能省,必須要開新的數保存,暫時不能改變dp的大小
32         等s0,s1,s2全部更新完以后才能去換,不然會影響結果,
33         假設余數為2:dp[0]=dp[0]+dp[1];
34                  dp[1]=dp[1]+dp[2];
35                  dp[2]=dp[2]+dp[0]+1;
36         如果這樣這樣更新會有一個問題,dp[0]改變之后,dp[2]=dp[2]+dp[0]+1;
37         用的就是新的dp[0],答案就不符合了
38         */
39         int s0=0,s1=0,s2=0;
40         int x=f(ch[i]);
41         if(x%3==0)
42         {
43            s0+=dp[0]+1;
44            s1+=dp[1];
45            s2+=dp[2];
46         }
47         if(x%3==1)
48         {
49             s0+=dp[2];
50             s1+=dp[0]+1;
51             s2+=dp[1];
52         }
53         if(x%3==2)
54         {
55             s0+=dp[1];
56             s1+=dp[2];
57             s2+=dp[0]+1;
58         }
59         //統一更新
60         dp[0]+=s0;
61         dp[1]+=s1;
62         dp[2]+=s2;
63         for(int j=0; j<3; j++)//每次對1e9+7取余;
64             dp[j]=dp[j]%Mod;
65     }
66     cout << dp[0] << endl;
67 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM