Sí, hay una manera. Considere el polinomio
(X + a[0]) * (X + a[1]) * ... * (X + a[n-1])
sus coeficientes son sólo las sumas de los k
-productos, su grado es n
, para que pueda calcular la suma de todos los k
-productos para todos k
simultáneamente en O (n^2) pasos .
Después s
pasos, el coeficiente de X s-k es la suma de los k
-productos de los primeros s
elementos de matriz. Los k
-productos de los primeros s+1
elementos se dividen en dos clases, los que implican la elemento (s+1)
st - estos tienen la -producto forma a[s]*((k-1)
de los primeros s
elementos) - y los que no implica que - estos son los k
-productos de los primeros elementos s
.
Código de tal manera que result[i]
es el coeficiente de X i (la suma de los (n-i)
-productos):
int *k_products_1(int *a, int n){
int *new, *old = calloc((n+1)*sizeof(int));
int d, i;
old[0] = 1;
for(d = 1; d <= n; ++d){
new = calloc((n+1)*sizeof(int));
new[0] = a[d-1]*old[0];
for(i = 1; i <= d; ++i){
new[i] = old[i-1] + a[d-1]*old[i];
}
free(old);
old = new;
}
return old;
}
Si sólo desea que la suma de los k
-productos para una k
, puede detener el cálculo en el índice n-k
, dando un algoritmo O (n * (nk)) - eso es bueno si k >= n/2
. Para obtener un algoritmo O (n * k) para k <= n/2
, debe organizar la matriz de coeficientes a la inversa, de modo que result[k]
sea el coeficiente de X nk (y detenga el cálculo en el índice k
si solo desea una suma):
int *k_products_2(int *a, int n){
int *new, *old = calloc((n+1)*sizeof(int));
int d, i;
old[0] = 1;
for(d = 1; d <= n; ++d){
new = calloc((n+1)*sizeof(int));
new[0] = 1;
for(i = 1; i <= d; ++i){
new[i] = old[i] + a[d-1]*old[i-1];
}
free(old);
old = new;
}
return old;
}
lo de k de nuevo? – Gevorg
¿Está tratando de evitar que todos los conjuntos existan en la memoria en un determinado momento o intente encontrar una solución que evite la idea de enumerar los subconjuntos por completo? Una solución recursiva parece estar bien para el primer requisito. – z5h
k es un número entero menor que la longitud de la lista L. – mitchus