3で割り切れるサブシーケンス問題レポート

質問の主な
アイデアへの質問リンク
長さ50の数字の文字列を入力し、3で割り切れる数を構成するサブシーケンスの数を尋ねます。
答えは1 e 9 + 7 1e ^ 9 +7です。1 e9+7モジュロ
入力の説明
数字で構成される文字列を入力します。長さは50以下です。
出力の説明
整数入力の例を出力し
ます。

132

サンプル出力

3

動的プログラミング線形dp1
。状態f [i] [j] f [i] [j]を決定しますf[i][j]:以 s [ i ] s[i] s [ i ]終わり残りはjjですj、属性はスキームの数を表します。
2.状態遷移f [i + 1] [j] = f [i + 1] [j] + f [i] [j] f [i + 1] [j] = f [i + 1] [j] + f [i] [j]f [ i+1 ] [ j ]=f [ i+1 ] [ j ]+f [ i ] [ j ]

キビを例として、サンプルを取り上げます。まず、132のサブシーケンスには1、3、13、2、12、32、132がありますある数は特定の数で割り切れるという結論があり、すべての位置の数の合計はこの数割り切れ、2で終わります。データは2、12、32、132です。12はf ["12"] [mod] = f ["12"] [(mod + "2")%mod] + f ["1"] [mod] f ["12"] [mod]と見なすことができます= f ["12"] [(mod + "2")\%mod] + f ["1"] [mod]f [ " 1 2 " ] [ m o d ]=f [ " 1 2 " ] [ m o d+" 2 " m o d ]+F [ " 1 " ] [ M O D ]など。
3.コーディングの実装

1      dp[1][1] = 1;
03     dp[2][0] = 1;
002    dp[3][2] = 1;

112  
13132 ⇒ dp[3][(j+2)%3] = (dp[2][j] + dp[3][(j+2)%3])
2
332

for(int i = 1; i <= len; i++)
    for(int j = 0; j < 3; j++)
        for(int k = i+1; k <= len; k++)
            f[k][(s[k]+j-'0')%3] =(f[k][(s[k]+j-'0')%3]+ f[i][j])%mod;
#include <cstdio>
#include <cstring>
using namespace std;
const int mod = 1e9 + 7;
char s[55];
int f[55][3];
int main()
{
    
    
    scanf("%s",s+1);
    int len = strlen(s+1);
    for(int i = 1; i <= len; i++) f[i][(s[i]-'0')%3] = 1;
    
    for(int i = 1; i <= len; i++)
        for(int j = 0; j < 3; j++)
            for(int k = i+1; k <= len; k++)
                f[k][(s[k]+j-'0')%3] =(f[k][(s[k]+j-'0')%3]+ f[i][j])%mod;
       
    int ans = 0;
    for(int i = 1; i <= len; i++) ans = (ans + f[i][0])%mod;
    printf("%d\n",ans);
    return 0;
}

おすすめ

転載: blog.csdn.net/Edviv/article/details/110931489