C. Add One
链接
https://codeforces.com/problemset/problem/1513/C
题目
思路
简单的dp:我使用的dp思路就是一个9经过n步最后有多少个数。很显然,如果只有1步那么就是两个。然后就是dp[n] = dfs(n-9)+dfs(n-10)
因为从9到9是10步和9步,然后如果dfs里面的数是负数那么直接返回1就行。所以这么多dp做下来感觉就是重复过程记忆化,然后找到递推就行。
代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
#define IOS ios::sync_with_stdio(false), cin.tie(0) ,cout.tie(0)
using namespace std;
#define int long long
const int M = 1e9 + 7;
const int N = 2e5 + 10;
int dp[N];
int dfs(int n)
{
//9走n步
if (n < 0)return 1;
if (dp[n])return dp[n];
if (n == 0)return dp[n]=1;
if (n <= 9)return dp[n]=2;
return dp[n] = (dfs(n - 9) + dfs(n - 10))%M;
}
signed main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t; cin >> t;
while (t--)
{
int n, m; cin >> n >> m;
map<int, int>mp;
string s = to_string(n);
for (int i = 0; i < s.length(); i++)
{
mp[s[i] - '0']++;
}
int ans = 0;
for (int i = 0; i <= 9; i++)
{
if (mp[i])
{
ans += dfs(m-(9 - i)) * mp[i];
ans %= M;
}
}
cout << ans << '\n';
}
return 0;
}