Я потратил более 1 часа на эту проблему. Какой должен быть ответ за n = 1
? Поэтому я думаю, что n
должно быть больше, чем 1 . Я предполагаю, что n > 1
.
Таким образом, решение с использованием грубой силы здесь не сработает, поскольку n
достаточно велико. Поэтому вам нужно более оптимизированное решение. Вам нужно подумать, сколько раз вам нужно carry 1
в сумме, чтобы сделать n
. Это самое большее 9
раз!
Если у вас есть какая-то базовая c идея с digit-dp(Dynamic Programming)
, тогда эта проблема проста. Постарайтесь разместить все возможные ди git на месте n и взять среди них минимум энергии. Эта проблема проста, когда вы полностью понимаете digit-dp
технику. Вы можете узнать это у здесь и здесь .
На практике вы можете найти множество проблем здесь ( Dynami c program section).
Для ваших ссылок я написал этот код только сейчас, и он работает правильно. Надеюсь, что вы можете использовать это как ссылку.
#include <bits/stdc++.h>
using namespace std;
const string INF_STRING = "9999999";
const int INF_INT = 9999999;
pair<string, int> INF = make_pair(INF_STRING, INF_INT);
int nod;
int digits[10];
int num_of_digits(int a) {
int cnt = 0;
while(a) {
digits[cnt] = a % 10;
a = a / 10;
cnt++;
}
return cnt;
}
pair<string, int> dp[10][2][2][2];
pair<string, int> solve(int ind, int carry, bool is1, bool is2) {
if(ind >= nod) {
if(carry != 0 || !is1 || !is2) return INF;
return make_pair("", 0);
}
pair<string, int> &ret = dp[ind][carry][is1][is2];
if(ret.second != -1) return ret;
ret = INF;
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
int s = (i + j + carry);
pair<string, int> cur = INF;
if(s % 10 == digits[ind]) {
cur = solve(ind + 1, s / 10, is1 || (i > 0? 1:0), is2 || (j > 0? 1:0));
}
if((cur.second + i + j) < ret.second) {
ret.second = cur.second + i + j;
ret.first = cur.first + (char)(i + '0');
}
}
}
return ret;
}
int stringToInt(string num) {
stringstream ss;
ss<<num;
int ret;
ss >> ret;
return ret;
}
int main() {
int i, t, cases = 1, j, k, pos;
int n;
scanf("%d", &n);
nod = num_of_digits(n);
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 2; j++) {
dp[i][j][0][0] = make_pair(INF_STRING, -1);
dp[i][j][0][1] = make_pair(INF_STRING, -1);
dp[i][j][1][0] = make_pair(INF_STRING, -1);
dp[i][j][1][1] = make_pair(INF_STRING, -1);
}
}
pair<string, int> res = solve(0, 0, 0, 0);
string num1_str = res.first;
int num1 = stringToInt(num1_str);
int num2 = n - num1;
printf("Minimum Energy: %d\n", res.second);
printf("Num1 = %d, Num2 = %d\n", num1, num2);
return 0;
}
/*
Input:
10000
Output:
Minimum energy: 10
Num1 = 1000, Num2 = 9000
*/