#include <stdio.h>
#include<stdlib.h>
#include <assert.h>
#include <string.h>
/*
9 5
7 11 12 5 3 20 6 5 2
7
11 | 12 | 5
3 | 20 | 6
5
2
~/test # ./tests
9 7
7 11 12 5 3 20 6 5 2
7 | 11 | 12 | 5
3 | 20 | 6 | 5
2
~/test # ./tests
9 3
7 11 12 5 3 20 6 5 2
7
11 | 12
5
3 | 20
6
5
2
*/
int main(void)
{//fun
int n ;
int k ;
int i ;
int sum,weight,w;
int *data, *line,*lineSave;
int getNextComb(int m,int r,int *p);
int getWeight(int *,int *,int );
int getSum(int *,int *,int );
int myPrint(int,int *,int * ,int );
scanf("%d%d", &n, &k);
assert(n >= k);
data=(int*)malloc(n*4);
line=(int*)malloc((k+1)*4);//1---k-1记录data的分割线位置,0位置0,k位置n
lineSave=(int*)malloc((k+1)*4);
for (i = 0; i < n; ++i)
scanf("%d", data+i);
for(i=0;i<k;++i)
{
line[i]=i;
lineSave[i]=i;
}
line[k]=n;
lineSave[k]=n;
weight=0x0fffffff;
while(getNextComb(n-1,k-1,line))
{//while01
w=getWeight(data,line,k+1);
if(w<weight)
{//if01
weight=w;
memcpy(lineSave,line,(k+1)*4);
}//if01
}//while01
sum=getSum(data,lineSave,k+1);
myPrint(sum,data,lineSave,k+1);
free(data);
free(line);
free(lineSave);
return 0;
}//fun
int getNextComb(int m,int r,int *p)
{//fun
int i,j;
i=r ;
while(p[i]==m-r+i && i>=1) --i;
if(i<1) return 0;
p[i]+=1;
for(j=i+1;j<=r;++j)
p[j]=p[j-1]+1;
return 1;
}//fun
int getWeight(int *data,int *line ,int r)//r为line数目
{
int i,j,v,weight=0;
for(i=1;i<r;++i)
{//for01
int s,e;
s=line[i-1];
e=line[i];
if(e-s>1)
for(j=s;j<e-1;++j)
for(v=j+1;v<e;++v)
weight+=data[j]*data[v];
}//for01
return weight;
}
int getSum(int *data,int *line ,int r)
{
int i,j,sum=0,m;
for(i=1;i<r;++i)
{//for01
m=0;
for(j=line[i-1];j<line[i];++j)
m+=data[j];
sum+=m*m;
}//for01
return sum;
}
int myPrint(int sum,int *data,int *line ,int r)
{
int i,j;
printf("%d\n",sum);
j=0;
printf("%d",data[0]);
++j;
for(i=1;i<r-1;++i)
{//for01
for(;j<line[i];++j)
printf(" %d",data[j]);
printf("|%d",data[j]);
++j;
}//for01
for(;j<line[r-1];++j)
printf(" %d",data[j]);
printf("\n");
return 0;
}
以上代码是枚举所有可能比较大小最后得到结果,这种方法效率比较低,以后再考虑优化算法吧,这种算法对负数适用。