C. Add One

https://codeforces.com/problemset/problem/1513/C

题意:给定一个长度为n的数字,执行每次操作,每次操作将n的所有位上的数字加1,满10后多一位变成两个单独的数,问操作后的数字长度是多少。

思路:动态规划,dp[i]表示数字10操作i次时当前的数字位数,递推公式dp[i] = dp[i - 10] + dp[i - 9],其中dp[0~8] = 2, dp[9] = 3。预处理好dp后,依次考虑n的每个位,看n与m相加是否>=10,然后累计答案即可。

总结:题目是把n按照单独的每一位来考虑的,而且一个数字操作若干次后不超过10,肯定不会发送位数变化,所以我们就以10为基础数值来考虑。那么问题转化成,数字10按照题目的规则,操作若干次后得到的数字位数是多少。先自己预演一下,可以得到dp0~8的初值,且操作8次后,得到的数字是98,9次是109,10次是2110,可以发现,第9次的时候又出现了一个数字10,第10次也出现了一个数字10,可以大致猜到,dp[i] = dp[i - 9] + dp[i - 10]。
有点抽象,搞了好几次的题目。

constexpr int N = 2e5 + 2333;
vector<MInt> dp(N);
inline void preProcess() {
	for (int i = 0; i < 9; ++i) {
		dp[i] = 2;
	}
	dp[9] = 3;
	for (int i = 10; i < N; ++i) {
		dp[i] = dp[i - 10] + dp[i - 9];
	}
}



inline void solve() {
	int n, m;
	cin >> n >> m;

	MInt ans = 0;
	while (n) {
		auto x = n % 10;
		n /= 10;
		if (x + m < 10) {
			ans ++;
		}
		else {
			ans += dp[m - (10 - x)];			
		}
	}

	cout << ans << '\n';

}
posted @ 2025-08-07 09:51  _Yxc  阅读(9)  评论(0)    收藏  举报