3で割り切れる部分列----------------------------思考(dp)

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

分析:
この線形dpも日常的な問題です
ブレークスルー:残りの3
fの処理[i] [0〜2]:以前のi数の合計が%3(0〜2)であるすべてのケースを表します

したがって、残りの状態を列挙するだけで済みます

状態遷移方程式:f [i] [j] = f [i-1] [j] + f [i-1] [(j + 3-m)%3]
f [i-1] [j]:平均i番目の番号は選択されず、i-1番号が選択され、残りは
f [i-1] [(j + 3-m)%3]:jを列挙するため、i番目の番号が選択されたことを意味します、i-1番目の数の残りが何であるかを判断する必要があります:(j + 3-m)%3 i番目の数の残りのみがmであり、jへの寄与は(m +(j + 3-m)%3)です%3 == j

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100;
const int MOD=1e9+7;
int f[N][3];
string s;
int main()
{
	cin>>s;
	int n=s.size();
	f[0][(s[0]-'0')%3]=1;
	for(int i=1;i<n;i++)
	{
		int m=(s[i]-'0')%3;
		f[i][m]=(f[i][m]+1)%MOD; 
		for(int j=0;j<=2;j++)
		{
			f[i][j]+=(f[i-1][j]+f[i-1][(3+j-m)%3])%MOD;
		}
	}
	cout<<f[n-1][0]<<endl;
}

公開された元の記事572件 賞賛された14件 ビュー10,000件以上

おすすめ

転載: blog.csdn.net/qq_43690454/article/details/105201942