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;
}

posted @ 2021-09-27 18:39  Xiaomostream  阅读(71)  评论(0编辑  收藏  举报