Si he entendido la pregunta correctamente, un poco de reflexión lo convencerá de que incluso la programación dinámica no es necesaria, la solución es completamente trivial.
Esta es la pregunta como yo lo entiendo: se le da una matriz de una [1] .. a [m] de 0s y 1s, y que se describen las operaciones de la forma S k, donde S k permitido significa voltear los N elementos a [k], a [k + 1], ... a [k + N-1]. Esto solo está definido para 1≤k≤M-N + 1, claramente.
Al realizar una secuencia de estas operaciones S k, desea alcanzar el estado de todos los 0, o todos los 1s. Solucionaremos ambos por separado y tomaremos el número más pequeño. Entonces supongamos que queremos hacer que sean todos 0 (el otro caso, todos 1s, es simétrico).
El idea fundamental es que nunca se quiere realizar ninguna operación S k más de una vez (haciendo dos veces es equivalente a no hacerlo en absoluto), y que el orden de las operaciones, no importa. Entonces la pregunta es solo para determinar qué subconjunto de las operaciones llevas a cabo, y esto es fácil de determinar. Mira un [1]. Si es 0, entonces sabe que no realizará S . De lo contrario, usted sabe que debe realizar S (ya que esta es la única operación que cambiará a [1]), realice esto - esto alternará todos los bits de un [1] a un [N]. Ahora mira a [2] (después de esta operación). Dependiendo de si es 1 o 0, usted sabe si realizará S o no. Y así sucesivamente: puede determinar cuántas operaciones (y cuáles) realizar, en tiempo lineal.
Editar: Se reemplazó el seudo código con el código C++, ya que hay una etiqueta C++. Perdón por el código feo; cuando estoy en el "modo concurso" vuelvo a los hábitos del concurso. :-)
#include <iostream>
using namespace std;
const int INF = 20000000;
#define FOR(i,n) for(int i=0,_n=n; i<_n; ++i)
int flips(int a[], int M, int N, int want) {
int s[M]; FOR(i,M) s[i] = 0;
int sum=0, ans=0;
FOR(i,M) {
s[i] = (a[i]+sum)%2 != want;
sum += s[i] - (i>=N-1?s[i-N+1]:0);
ans += s[i];
if(i>M-N and s[i]!=0) return INF;
}
return ans;
}
int main() {
int M = 6, N = 3;
int a[] = {1, 0, 0, 1, 0, 0};
printf("Need %d flips to 0 and and %d flips to 1\n",
flips(a, M, N, 0), flips(a, M, N, 1));
}
1. ¿Es esta tarea? 2. ¿Qué tan grandes son M y N? (Por ejemplo, ¿funcionaría un algoritmo O (M 2^N)?) 3. Su inglés está perfectamente bien. No creo que este problema tenga un título famoso. – ShreevatsaR
¿El problema garantiza que siempre hay una solución?Para 1 0 1 y N = 3, por ejemplo, no hay solución. ¿Debe el algoritmo tener en cuenta estos casos o no? – IVlad
Probablemente obtendrá más respuestas si prueba el problema, ponga algún código o pseudocódigo en su pregunta y luego solicite comentarios. – thebretness