做递归时碰到问题未解决,为尽快得到结果,就根据递归算法衍生出“加法计算器算法”,已经完全能穷尽所有组合,得到的结果和题主给出的结果完全一样,效果及代码如下:
测试效果:
程序代码:
N=9, K=7
7 11 12 5 3 20 6 5 2
7 |11 |12 | 5 3 |20 | 6 | 5 2 --------Sum=863
N=9, K=5
7 11 12 5 3 20 6 5 2
7 11 |12 | 5 3 |20 | 6 5 2 --------Sum=1101
N=4, K=2
6 2 2 6
6 2 | 2 6 --------Sum=128
N=5, K=3
100 1 1 1 1
100 | 1 1 | 1 1 --------Sum=10008
N=17, K=5
15 3 18 3 21 7 14 2 17 9 20 2 38 4 35 6 23
15 3 18 3 |21 7 14 2 |17 9 20 | 2 38 4 |35 6 23 --------Sum=11605
N=17, K=10
15 3 18 3 21 7 14 2 17 9 20 2 38 4 35 6 23
15 3 |18 3 |21 | 7 14 | 2 17 | 9 |20 2 |38 | 4 35 | 6 23 --------Sum=6379
N=17, K=13
15 3 18 3 21 7 14 2 17 9 20 2 38 4 35 6 23
15 3 |18 3 |21 | 7 |14 2 |17 | 9 |20 2 |38 | 4 |35 | 6 |23 --------Sum=5615
N=18, K=4
22 3 4 30 39 18 20 29 32 28 25 28 11 17 19 35 21 28
22 3 4 30 39 |18 20 29 32 |28 25 28 11 17 |19 35 21 28 --------Sum=41895
N=19, K=6
27 47 24 23 32 10 29 3 33 48 48 20 22 11 19 49 21 45 16
27 47 24 |23 32 10 29 | 3 33 48 |48 20 22 |11 19 49 |21 45 16 --------Sum=46561
N=19, K=13
27 47 24 23 32 10 29 3 33 48 48 20 22 11 19 49 21 45 16
27 |47 |24 23 |32 |10 29 | 3 33 |48 |48 |20 22 |11 19 |49 |21 |45 16 --------Sum=22823
N=24, K=8
27 31 9 23 37 7 7 18 32 4 8 32 41 8 11 22 22 5 21 32 7 11 33 13
27 31 9 |23 37 | 7 7 18 32 | 4 8 32 |41 8 |11 22 22 5 |21 32 7 |11 33 13 --------Sum=26971
N=24, K=13
27 31 9 23 37 7 7 18 32 4 8 32 41 8 11 22 22 5 21 32 7 11 33 13
27 |31 | 9 23 |37 | 7 7 18 |32 4 | 8 32 |41 | 8 11 22 |22 5 21 |32 | 7 11 |33 13 --------Sum=17133
N=24, K=18
27 31 9 23 37 7 7 18 32 4 8 32 41 8 11 22 22 5 21 32 7 11 33 13
27 |31 | 9 23 |37 | 7 7 |18 |32 | 4 8 |32 |41 | 8 11 |22 |22 | 5 21 |32 | 7 11 |33 |13 --------Sum=13087
测试代码:
程序代码:
#include <stdio.h>
int setcount(int *a,int n,int k)
{//调整计数器,如果计数器内值不合法,则返回True
int i,j;
for(i=j=0;i<k;i++)
{
if(!a[i])a[i]=j+1;
j=a[i];
}
for(i=0;i<k&&a[i]<=n;i++);
return i<k;
}
int inccount(int *a,int n,int k)
{//计数器加1,并根据结果调整各位合法值,如果计数器第0位数据和数据位数的和大于总数据,则不合法,返回false
int i,f=1;
do
{
if(a[0]+k>n)return 0;
for(i=k;i;i--)
{
a[i-1]+=f;
f=0;
if(a[i-1]>n)
{
a[i-1]=0;
f=1;
}
}
f=0;
}while(setcount(a,n,k));
return 1;
}
int sumsqu(int *a,int *b,int n,int k)
{//分段求平方和并返回
int i,j,l,sum;
for(i=j=l=sum=0;i<k-1;i++)
{
for(;j<b[i];j++)l+=a[j];
sum+=l*l;
l=0;
}
for(;j<n;j++)l+=a[j];
sum+=l*l;
return sum;
}
int main()
{
int i,j,a[100],b[100],c[100],n,k;
while(scanf("%d%d",&n,&k)&&n&&k)
{
for(i=0;i<n;i++)
{
b[i]=c[i]=0;
scanf("%d",&a[i]);
}
setcount(b,n-1,k-1);
while(inccount(b,n-1,k-1))
{
if(sumsqu(a,b,n,k)<sumsqu(a,c,n,k))
{
for(i=0;i<k;i++)c[i]=b[i];
}
}
printf("N=%d, K=%d\n",n,k);
for(i=0;i<n;i++)printf("%d ",a[i]);
printf("\n");
for(i=j=0;i<n;i++)
{
printf("%2d ",a[i]);
if(i==c[j])
{
printf("|");
j++;
}
}
printf("--------Sum=%d\n",sumsqu(a,c,n,k));
}
}