Title Description
Given a number string, add the minimum number of times to make the string equal to a given target number. Each addition is to insert a plus sign somewhere in the string. After all the plus signs in it are inserted, they are evaluated just like ordinary addition.
For example, consider the string "12", add 0 times, and we get the number 12. If we insert a plus sign, we get 3, so in this case, we get the number 3 by adding at least once
For another example, considering the string "303" and the target number 6, the best method is not "3 + 0 + 3". It's "3 + 03.". This can be done because the leading 0 of a number does not change its size.
Write a program to implement the algorithm.
I / O format
Input format:
Line 1: 1 string s (length of 1 < = s < = 40);
Line 2: 1 integer n (n < = 100000).
Output format:
Line 1: an integer K, indicating that the minimum number of addition times makes S equal to n. If nothing can be done to make S equal to N, output - 1
Example of input and output
Input example ා 1:copy
99999 45
Output example:copy
4
Explanation:
At first, I thought about violent solution, but I found that since the code could not be written, I thought about dfs
Let me start with the dfs Code:
#include <iostream> using namespace std; string s; int n, ans = 1000, maxplus; int a[50]; bool flag = 0; int turn(int start, int end) { //Return from value record of a + b int sum = 0; for(int i = start; i <= end; ++i) sum *= 10,sum += a[i]; return sum; } void dfs(int now, int step, int cntplus) { //Current value current plus sign position current plus sign quantity if(cntplus > maxplus) return; //Stop when found, and stop when the plus sign is greater than the maximum number if(now == n) { // Find all stop flag = 1; ans = min(ans,cntplus); return; } for(int i = step + 1; i < s.size(); ++i) //Look for it later dfs(now + turn(step + 1, i),i,cntplus + 1); } int main() { cin >> s >> n; for(int i = 0; i < s.size(); i++) { a[i] = s[i] - '0'; } maxplus = s.size() - 1; //Maximum number of plus signs for(int i = 0; i < s.size() - 1; ++i) dfs(turn(0,i), i, 0); //The first plus digger has a special situation of 00000 if(flag ) cout << ans ; else cout << -1 ; return 0; }
It's hard not to pass three test cases.
Here's the dp Code: in special cases, there are two groups
0000 0 222 0
//The minimum addition times of the first i-digit component j f[i][j] = min {f [i-k] [j-s [i-k + 1], f[i][j]}
The explanation code is very detailed.
#include <iostream> #include <cstring> using namespace std; const int INF = 0x3f3f3f3f, maxn = 100001; int n, a[41], dp[42][maxn], sum[42][42] = {0};// The minimum addition times f [i] [j] = min {f [i-k] [j-s [i-k + 1] string s; int main() { cin >> s; int len = s.size(); for(int i = 0; i < len; i ++) a[i + 1] = s[i] - '0'; for(int i = 1; i <= len; i++) { sum[i][i] = a[i]; for(int j =i + 1; j <= len; j++) sum[i][j] += sum[i][j - 1] * 10 + a[j]; //sum represents the value from i to j } cin >> n; if(!n&&!sum[1][len]) return cout << 0,0; memset(dp, 0x3f, sizeof(dp)),dp[0][0] = 0; for(int i = 1; i <= len; i++) for(int k = 1; k <= len && k <= 6; k++) if(k <= i) //k < i for(int j = sum[i - k +1][i]; j <= n; j++) dp[i][j] = min(dp[i-k][j-sum[i-k+1][i]] + 1,dp[i][j]); //Minimum steps from dp to i to j if(dp[len][n] == INF) cout << -1 ; else cout << dp[len][n] - 1; return 0; }