D - FG operation
题意
给你n个【0,9】的数,从左到右,每次可以选取最左边的两个数进行 F.相加mod10 or G.相乘mod10 两个操作,然后删除这两个数,新加上mod10后得到的数,问合并到只有一个的所有操作方案【0,9】的数量
思路
如果暴力二进制枚举显然有 2^n 次方种方案,肯定LTE
可以考虑线性dp去解决
状态表示:
DP[i][j] 表示前i个数进行合并最后的数字为j( 0<=j<=9 )的方案数;
状态转移:
DP[i][(a[i]+j)%10] = DP[i][(a[i]+j)%10] + DP[i-1][j] ①
DP[i][(a[i]*j)%10] = DP[i][(a[i]*j)%10] + DP[i-1][j] ②
代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#include <queue>
#include <vector>
#define endl '\n'
using namespace std;
void IOS(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
}
typedef pair<int,int> PII;
typedef long long ll;
const int maxn=1e5+5;
int dp[maxn][10];
int a[maxn];
const int mod = 998244353;
int main(){
int n;
cin >> n;
for(int i = 1; i <= n ; i ++) cin >> a[i];
dp[1][a[1]]=1;//记得初始化为1
for(int i = 2; i <= n; i ++)
{ for(int j = 0; j <= 9; j ++)
{
dp[i][(a[i]+j)%10]=(dp[i][(a[i]+j)%10]+dp[i-1][j])%mod;
dp[i][(a[i]*j)%10]=(dp[i][(a[i]*j)%10]+dp[i-1][j])%mod;
}
}
for(int i = 0; i <= 9; i ++)
cout<<dp[n][i]<<endl;
return 0;
}