【CF908G】New Year and Original Order
阿新 • • 發佈:2019-01-05
【CF908G】New Year and Original Order
題面
題解
設\(f[i][j][k][l]\)表示當前在第\(i\)位有\(j\)位大於等於\(k\),當前有沒有卡上界的方案數
則列舉新加的數\(p\),有
\[ f[i+1][j+(p\geq k)][k][l|(p<a_i)]=\sum f[i][j][k][l] \]
我們最後統計答案的時候列舉\(k\)
有
\[ ans=\underbrace{111...11}_{j個1}*(f[i][j][k][0]+f[i][j][k][1]) \]
為什麼要乘那麼多\(1\)呢?(下面是張圖片)
程式碼(壓行有點醜
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define rep(i, from, to) for(int i = (from); i <= (to); i++) const int Mod = 1e9 + 7; const int MAX_N = 1005; void pls(int &x, int y) { x += y; if (x >= Mod) x -= Mod; } char ch[MAX_N]; int a[MAX_N], N; int ans, f[MAX_N][MAX_N][10][2]; int main () { scanf("%s", ch + 1); N = strlen(ch + 1); rep(i, 1, N) a[i] = ch[i] - '0'; rep(i, 0, 9) f[0][0][i][0] = 1; rep(i, 0, N - 1) rep(j, 0, i) rep(k, 1, 9) rep(l, 0, 1) rep(p, 0, (l ? 9 : a[i + 1])) pls(f[i + 1][j + (p >= k)][k][l | (p < a[i + 1])], f[i][j][k][l]); rep(k, 1, 9) { int res = 1; rep(i, 1, N) pls(ans, 1ll * res * (f[N][i][k][0] + f[N][i][k][1]) % Mod), res = (10ll * res + 1) % Mod; } printf("%d\n", ans); return 0; }