快速求和递归的递归没有得到正确的结果

Not getting proper result with my recursion for quick sum recursion

给定一串数字,找到使该字符串等于某个目标数字所需的最少加法次数。每次加法都相当于在数字串的某处插入一个加号。

示例: “1110”

目标 3

return 3 因为 1+1+1+0=3 需要 3 次加法。

"0123456789"

目标 45

Returns: 8

"99999"

目标 100

Returns:-1

"382834"

100

Returns: 2

100有3种方法,分别是38+28+34、3+8+2+83+4、3+82+8+3+4。最少需要 2 个。

我试过这个问题,这是我的代码。我第一次考虑一个角色并得到结果。下次我使用 2 个字符并获得结果时,依此类推,直到我尝试了最大 string.I 大小的所有字符,我没有得到正确的递归。

    int min(int a,int b)
    {
        return a>b?b:a;
    }

    /* i is current index we are considering and sum is total number
     *of + required
     */
    int foo(char *a, int size, int i, int current_stock, int target, int sum){
        unsigned long long int mini = 1 << 30; /* huge number */
        int number=0, mul, m;
        int p = i;
        if (i+current_stock>size)
            return mini;
        if (target == 0)
            return sum;
        if (target < 0)
            return mini;
        mul = 1;
        /* make the multiplier */
        for (m=1;m<current_stock;m++) {
            mul *= 10;
        }
        /* make the number from i to current_stock
         * if the string is 123 and if i is 0 and current_stock is 2
         * then the number will be 12 */
        for (m=0;m<current_stock;m++) {
            number += (a[p]-'0')*mul;
            mul = mul/10;
            p++;
        }

        sum = sum + 1;
        for(m=current_stock;m<=size;m++) {
            mini = min(mini, foo (a, size, i+current_stock, m, target-number, sum));
        }
        return mini;
    }

    int main(void) {
        char a[] = "382834";
        printf("%d", foo(a, strlen(a), -1, 1, 100, 0));
        printf("%d\n", strlen(a));
        return 0;
    }

我编写了您提到的确切解决方案,它似乎对我有用。只是一个变化,你不需要去到所有的角色,如果你已经越过了目标然后就可以提前打破。

#define INFINITY 100000
long int result[20][1000];

long int solve(char *str,long int i,long int target){
    long int min=INFINITY;
    long int number=0,base=10;
    long int j=i;
    long int score1;
    //memoized result
    if(result[i][target]!=-2){
        return result[i][target];
    }

    //if target is achieved and string is finished
    if(i==strlen(str) && target==0){
        return 0;
    }
    // if string finished but target not achieved
    if(i==strlen(str)&& target!=0){
        return -1;
    }

    while(j<strlen(str)){
        long int digit=str[j]-'0';
        number=number*base+digit;
        if(number <=target){
            score1=solve(str,j+1,target-number);
            if(score1!=-1){
                if(j<(strlen(str)-1))
                    score1=score1+1;
                if(score1<min){
                    min=score1;
                }
            }
        }
        else{
            break;
        }
        j++;
    }
    if(min<INFINITY)
        result[i][target]=min;
    else
        result[i][target] = -1;
    return result[i][target];
}

对于非计算值,我正在用 -2 初始化我的记忆数组结果。我检查了所有给出的测试用例,它正在工作。请检查解决方案,让我知道它是否有意义。

我想@Naman 给你找到了解决方案,但你工作太辛苦了。只需将第一个加号放在每个可能的位置,然后重复放置其余的。基本情况是所有数字都等于目标。在这种情况下,所需的加数为零。

#include <stdio.h>
#include <string.h>
#define NO_SOLUTION (-1)

int find_min_plusses(int target, char *digits, int n_digits) {
  int min = NO_SOLUTION, val = 0, i;
  for (i = 0; i < n_digits - 1; i++) {
    val = val * 10 + (digits[i] - '0');
    if (val > target) return min;
    int rest = find_min_plusses(target - val, digits + i + 1, n_digits - i - 1);
    if (rest != NO_SOLUTION && (min == NO_SOLUTION || rest + 1 < min))
      min = rest + 1;
  }
  val = val * 10 + (digits[i] - '0');
  return val == target ? 0 : min;
}

int main(int argc, char *argv[]) {
  int target;
  if (argc == 3) {
    if (sscanf(argv[1], "%d", &target) != 1) return 1;
    int min = find_min_plusses(target, argv[2], strlen(argv[2]));
    printf("%d\n", min);
  }
  return 0;
}

在这里你可以观看运行。每一行都是一个调用。

./a.out 100 382834
tgt=100,digits=382834,n_digits=6
tgt=97,digits=82834,n_digits=5
tgt=89,digits=2834,n_digits=4
tgt=87,digits=834,n_digits=3
tgt=79,digits=34,n_digits=2
tgt=76,digits=4,n_digits=1
tgt=4,digits=4,n_digits=1
tgt=61,digits=34,n_digits=2
tgt=58,digits=4,n_digits=1
tgt=15,digits=834,n_digits=3
tgt=7,digits=34,n_digits=2
tgt=4,digits=4,n_digits=1
tgt=62,digits=2834,n_digits=4
tgt=60,digits=834,n_digits=3
tgt=52,digits=34,n_digits=2
tgt=49,digits=4,n_digits=1
tgt=34,digits=34,n_digits=2
tgt=31,digits=4,n_digits=1
2