BZOJ 5544: [PA2019]A + B
设 \(f_i\) 为前 \(i\) 位能由多少种方案组成
那么要么就是正常的得到方式,可以由 \(f_{i-1}\) 转移来,方案数为 \(f_{i-1} \times cnt_{s_i}\)
错误的得到方式就由 \(f_{i-2}\) 转移得来,方案数为 \(f_{i-2} \times cnt_{s_{i-1}, s_i}\)
#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define pii pair<int, int>
#define pli pair<ll, int>
#define SZ(x) ((int)(x).size())
#define lp p << 1
#define rp p << 1 | 1
#define mid ((l + r) / 2)
#define lowbit(i) ((i) & (-i))
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=((b)-1);i>=(a);i--)
#define Edg int ccnt=1,head[N],to[E],ne[E];void addd(int u,int v){to[++ccnt]=v;ne[ccnt]=head[u];head[u]=ccnt;}void add(int u,int v){addd(u,v);addd(v,u);}
#define Edgc int ccnt=1,head[N],to[E],ne[E],c[E];void addd(int u,int v,int w){to[++ccnt]=v;ne[ccnt]=head[u];c[ccnt]=w;head[u]=ccnt;}void add(int u,int v,int w){addd(u,v,w);addd(v,u,w);}
#define es(u,i,v) for(int i=head[u],v=to[i];i;i=ne[i],v=to[i])
const int MOD = 1000000007,INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
void M(int &x) {if (x >= MOD)x -= MOD; if (x < 0)x += MOD;}
int qp(int a, int b = MOD - 2, int mod = MOD) {int ans = 1; for (; b; a = 1LL * a * a % mod, b >>= 1)if (b & 1)ans = 1LL * ans * a % mod; return ans % mod;}
template<class T>T gcd(T a, T b) { while (b) { a %= b; std::swap(a, b); } return a; }
template<class T>bool chkmin(T &a, T b) { return a > b ? a = b, 1 : 0; }
template<class T>bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
const int N = 30;
int a[N], b[N][N];
char s[N];
ll f[N];
int main() {
#ifdef LOCAL
freopen("ans.out", "w", stdout);
#endif
rep (i, 0, 10) {
rep (j, 0, 10) {
int k = i + j;
if (k < 10) a[k]++;
else b[k / 10][k % 10]++;
}
}
scanf("%s", s + 1);
f[0] = 1;
int n = strlen(s + 1);
rep (i, 0, n) {
f[i + 1] += f[i] * a[s[i + 1] - '0'];
f[i + 2] += f[i] * b[s[i + 1] - '0'][s[i + 2] - '0'];
}
printf("%lld\n", f[n]);
#ifdef LOCAL
printf("%.10f\n", (db)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}