C. Add One
题目大意
给你一个数然后进行k次操作,要求让你对每一位加一。问k次操作后这个数会变成多少位。
思路
每一位加一变化时,只有9加一会多变出一位,那么进行预处理,用二维数组进行dp,先看9加1到10,多出1位,dp[0~9][k次操作],8加2呢是不是也是10,那么dp[8][2]=dp[9][1],那么这样子在不等于9的情况下,dp[i][j]=d[i+1][j-1],如果为9时,使得结果是由上面式子如何推出呢?,其实可以这样理解dp[9][j]=dp[10][j-1],而10又被分成了0和1,那么dp[9][j]=dp[1][j-1]+dp[0][j-1]。那么本体迎刃而解。
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
using namespace std;
#define ll long long
#define sl(n) scanf("%lld",&n)
#define pl(n) printf("%lld",n)
#define sdf(n) scanf("%lf",&n)
#define pdf(n) printf("%.lf",n)
#define pE printf("\n")
#define ull unsigned long long
#define pb push_back
#define debug(a) cout<<a<<"??"
#define me(a) memset(a,0,sizeof(a))
#define pre(n) for(ll i=1;i<=n;i++)
#define rep(n) for(ll i=n;i>=1;i--)
#define ph push
#define pi pair<ll,ll>
#define fi first
#define se second
const ll mod = 1e9 + 7;
ll dp[11][200010], a[11];
void done()
{
int i, j;
for (i = 1; i <= 200010; i++)
{
for (j = 0; j < 9; j++)
{
dp[j][i] = dp[j + 1][i - 1] % mod;
}
dp[9][i] = (dp[9][i] + dp[1][i - 1] + dp[0][i - 1]) % mod;
}
return ;
}
void solve(ll k)
{
ll ans = 0, i;
for (i = 0; i <= 9; i++)
{
ans = (ans + a[i] * dp[i][k] % mod) % mod;
}
cout << ans << endl;
return ;
}
int main()
{
ll t, n, k;
sl(t);
for (int i = 0; i < 10; i++)dp[i][0] = 1;
done();
while (t--)
{
ll len = 0;
sl(n), sl(k);
me(a);
while (n)
{
a[n % 10]++;
n /= 10;
}
solve(k);
}
for (int i = 1; i <= 10; i++)
{
for (int j = 0; j <= 9; j++)cout << dp[j][i] << ' ';
puts("");
}
return 0;
}
一维dp
当你分解出来的每一位数,如果加上k小于10那么位数就是1,如果位数如果大于10,你从dp[i+m-10]开始算起,每一位记录此时的下标从的0代表大于9的数能变出的位数,每多10位数发生变化,所以转移方程就是dp[i]=dp[i-10]+dp[i-9]
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
using namespace std;
#define ll long long
#define sl(n) scanf("%lld",&n)
#define pl(n) printf("%lld",n)
#define sdf(n) scanf("%lf",&n)
#define pdf(n) printf("%.lf",n)
#define pE printf("\n")
#define ull unsigned long long
#define pb push_back
#define debug(a) cout<<a<<"??"
#define me(a) memset(a,0,sizeof(a))
#define pre(n) for(ll i=1;i<=n;i++)
#define rep(n) for(ll i=n;i>=1;i--)
#define ph push
#define pi pair<ll,ll>
#define fi first
#define se second
const ll mod = 1e9 + 7;
ll dp[200010];
int main()
{
ll i, t, n, m, ans, cur;
for (i = 0; i <= 8; i++)dp[i] = 2;
dp[9] = 3;
for (i = 10; i <= 200010; i++)
{
dp[i] = (dp[i - 9] + dp[i - 10]) % mod;
}
sl(t);
while (t--)
{
sl(n), sl(m);
ans = 0;
while (n)
{
cur = n % 10;
if (cur + m - 10 < 0) ans = (ans + 1) % mod;
else ans = (ans + dp[cur + m - 10]) % mod;
n /= 10;
}
cout << ans << endl;
}
return 0;
}