Algorithm 我可以将数组划分为K个大小吗?

Algorithm 我可以将数组划分为K个大小吗?,algorithm,dynamic-programming,partitioning,greedy,Algorithm,Dynamic Programming,Partitioning,Greedy,我试图实现这个问题中的算法,但我缺少一些边缘情况,这导致我的代码进入无限循环。我可以通过做一些表面上的改变来修复它,但这表明我不理解算法 有人能帮我吗,我错过了什么 #include <stdio.h> #define max(a, b) (((a)>(b))?(a):(b)); int get_max(int *a, int i, int size) { if (i >= size) return 0; return max(a[i],

我试图实现这个问题中的算法,但我缺少一些边缘情况,这导致我的代码进入无限循环。我可以通过做一些表面上的改变来修复它,但这表明我不理解算法

有人能帮我吗,我错过了什么

#include <stdio.h>

#define max(a, b) (((a)>(b))?(a):(b));
int get_max(int *a, int i, int size)
{
    if (i >= size)
        return 0;
    return max(a[i], get_max(a, i+1, size));
}

int get_sum(int *a, int i, int size)
{
    if (i >= size)
        return 0;
    return a[i] + get_sum(a, i+1, size);
}

int get_partition(int *a, int size, int bound) {
    int running_sum = 0;
    int partitions = 0, i;

    for (i=0;i<size;i++) {
        if (a[i] + running_sum <= bound) {
            running_sum += a[i];
        } else {
            running_sum = 0;
            running_sum += a[i];
            partitions++;
        }
    }
    return partitions;
}

int foo(int *a, int size, int k)
{
    int lower = get_max(a, 0, size);
    int higher = get_sum(a, 0, size);
    int partition;

    while (lower < higher) {
        int bound = (lower + (higher))/2;

        partition = get_partition(a, size, bound);
        printf("partition %d bound %d lower %d higher %d\n", partition, bound, lower, higher);
        if (partition >= k) 
            lower = bound;
        else
            higher = bound;
    }
    return partition;
}

#define SIZE(a) sizeof(a)/sizeof(a[0])
int main(void) {
    int a[] = {2, 3, 4, 5, 6};
    printf("%d\n", foo(a, SIZE(a), 3));
    return 0;
}

您有两个错误:

  • 在二进制搜索过程中,您的while测试应该是
    while(lower+1
    ,而不是
    while(lower
    。当
    lower=8
    higher=9
    时,您将进入无限循环。在此阶段,您的
    边界将是
    (lower+higher)/2=8,您将更新
    lower=bound
    ,这不会改变任何内容
  • foo
    的末尾,您应该返回
    higher
    (而不是partitions),因为您的二进制搜索不变量是具有
    bound=higher
    的不变量,您可以将其划分为
    k
    或更少
  • 您对
    get\u partition
    的计算是错误的。您没有考虑最后一个分区组的帐户,因为您只有在溢出
    运行\u sum
    时才更新
    分区

    if (running_sum > 0) 
        partitions++; 
    
总而言之:

#include <stdio.h>

#define max(a, b) (((a)>(b))?(a):(b));
int get_max(int *a, int i, int size)
{
    if (i >= size)
        return 0;
    return max(a[i], get_max(a, i+1, size));
}

int get_sum(int *a, int i, int size)
{
    if (i >= size)
        return 0;
    return a[i] + get_sum(a, i+1, size);
}

int get_partition(int *a, int size, int bound) {
    int running_sum = 0;
    int partitions = 0, i;

    for (i=0;i<size;i++) {
        if (a[i] + running_sum <= bound) {
            running_sum += a[i];
        } else {
            running_sum = 0;
            running_sum += a[i];
            partitions++;
        }
    }
    if (running_sum > 0)
        partitions++;
    return partitions;
}

int foo(int *a, int size, int k)
{
    int lower = get_max(a, 0, size);
    int higher = get_sum(a, 0, size);
    int partition;

    while (lower+1 < higher) {
        int bound = (lower + (higher))/2;

        partition = get_partition(a, size, bound);
        printf("partition %d bound %d lower %d higher %d\n", partition, bound, lower, higher);
        if (partition > k)
            lower = bound;
        else
            higher = bound;
    }
    printf("partition %dlower %d higher %d\n", partition, lower, higher);
    return higher;
}

#define SIZE(a) sizeof(a)/sizeof(a[0])
int main(void) {
    int a[] = {2, 3, 4, 5, 6};
    printf("%d\n", foo(a, SIZE(a), 3));
    return 0;
}
#包括
#定义max(a,b)((a)>(b))?(a):(b));
int get_max(int*a,int i,int size)
{
如果(i>=大小)
返回0;
returnmax(a[i],get_max(a,i+1,size));
}
int get_sum(int*a,int i,int size)
{
如果(i>=大小)
返回0;
返回一个[i]+get_和(a,i+1,size);
}
int-get_分区(int*a,int-size,int-bound){
int运行_sum=0;
int分区=0,i;
对于(i=0;i k)
下限=下限;
其他的
更高=界限;
}
printf(“分区%d低%d高%d\n”,分区,低,高);
回报更高;
}
#定义大小(a)sizeof(a)/sizeof(a[0])
内部主(空){
inta[]={2,3,4,5,6};
printf(“%d\n”,foo(a,大小(a),3));
返回0;
}

请包括输出的前两行和前三行。猜测:lower==bound==higher-1#include <stdio.h> #define max(a, b) (((a)>(b))?(a):(b)); int get_max(int *a, int i, int size) { if (i >= size) return 0; return max(a[i], get_max(a, i+1, size)); } int get_sum(int *a, int i, int size) { if (i >= size) return 0; return a[i] + get_sum(a, i+1, size); } int get_partition(int *a, int size, int bound) { int running_sum = 0; int partitions = 0, i; for (i=0;i<size;i++) { if (a[i] + running_sum <= bound) { running_sum += a[i]; } else { running_sum = 0; running_sum += a[i]; partitions++; } } if (running_sum > 0) partitions++; return partitions; } int foo(int *a, int size, int k) { int lower = get_max(a, 0, size); int higher = get_sum(a, 0, size); int partition; while (lower+1 < higher) { int bound = (lower + (higher))/2; partition = get_partition(a, size, bound); printf("partition %d bound %d lower %d higher %d\n", partition, bound, lower, higher); if (partition > k) lower = bound; else higher = bound; } printf("partition %dlower %d higher %d\n", partition, lower, higher); return higher; } #define SIZE(a) sizeof(a)/sizeof(a[0]) int main(void) { int a[] = {2, 3, 4, 5, 6}; printf("%d\n", foo(a, SIZE(a), 3)); return 0; }