Corte de papel llameante

Markdown no estaba acostumbrado a esto por primera vez, y tomó mucho tiempo. . . . . .

Corte de papel llameante

度度熊有一张纸条和一把剪刀。

纸条上依次写着 N 个数字,数字只可能是 0 或者 1。

度度熊想在纸条上剪 K 刀(每一刀只能剪在数字和数字之间),这样就形成了 K+1 段。

他再把这 K+1 段按一定的顺序重新拼起来。

不同的剪和接的方案,可能会得到不同的结果。

度度熊好奇的是,前缀 1 的数量最多能是多少。

De entrada

有多组数据,读到EOF结束。

对于每一组数据,第一行读入两个数 N 和 K 。

第二行有一个长度为 N 的字符串,依次表示初始时纸条上的 N 个数。

0≤K<N≤10000

所有数据 N 的总和不超过100000

Salida

对于每一组数据,输出一个数,表示可能的最大前缀 1 的数量。

Muestra

De entrada

5 1
11010
5 2
11010

Salida

2
3



#include <iostream> 

#include <cstring> 

#include <algorithm> usando el espacio de nombres std; int num [ 100005 ]; int cmp ( int a, int b) { return a> b; 
} int main () { int n, k; while (scanf ( " % d% d " , & n, & k) == 2 ) { string s; 
        cin >> s; int all = 0 , i;  // 所有 的 1 para (i = 0

 

 





    




    

    

        


        

        ; i <n; i ++)     if (s [i] == ' 1 ' ) all ++ ; 

 

        int pre = 0 ;     // front 'contínuo 1' 

        para (i = 0 ; i <n; i ++ ) { 

            if (s [i] == ' 1 ' ) pre ++ ; 

            else   break ; 

        } 

        int left1 = 0 ;   // detrás de 'contínuo 1' 

 

        if (pre! = all) { // tenga en cuenta que la posible cadena s es todo 1 

            para (i = n- 1 ; i> = 0 ; i-- ) { 

                if (s [i] == '1 ' ) left1 ++ ; 

                else   break ; 

            } 

        } 

        memset (num, 0 , sizeof (num)); 

        int j = 0 , flag;                   // j: indica el número de' continuo 1 'en el medio 

        para (i = pre; i < n-left1; i ++) {    // almacena el medio 'continuo 1', usa num [] para almacenar 

            flag = 0 ; 

            while (s [i] == ' 1 ' && i < n) { 

                num [j] ++ ; 

                i ++ ; 

                flag =1 ; 

            } 

            if (flag) j ++ ;         

        } 

        sort (num, num + j, cmp);         // El 'continuo 1' del medio se ordena de grande a pequeño 

        int sum = 0 , cur = k;             // cur: indica la corriente El número restante de cuchillos 

        

        // comienza la estrategia codiciosa, primero trata con el medio, presta atención a dejar dos cuchillos, porque el primero y el último solo se pueden reducir en un cuchillo 

        para (i = 0 ; i <j && cur> 2 ; i ++) {   // El 'continuo 1' en el medio, debes cortar con dos cuchillos 

            suma + = num [i]; 

            num [i] = 0 ;                 // Eliminar 

            cur- = 2 ;

        } 

        

        // Juzgar los dos últimos cuchillos 

        para (i = 0 ; i <j; i ++)   if (num [i]! = 0 ) break ;    // encuentra el 'continuo 1' más grande 

        si no se corta en el medio (cur> = 2 ) {                                // Si el número restante de cuchillos> = 2, son los dos más grandes de num [i], pre, left1 y los tres (razón: demuéstralo en el borrador) 

            si (pre <= left1 && pre <= NUM [I]) Suma + = (left1 + NUM [I]); 

            el otro  IF (left1 <= pre && left1 <= NUM [I]) Suma + = (pre + NUM [I]); 

            el otro   SUM + = ( left1 + pre); 

        } else  if (cur == 1 ) {                        // El número restante de cuchillos == 1, es decir k == 3, dos casos: 1. cortar el centro, 2. cortar la cola (tenga en cuenta que si se corta la cola, el primer 1 también se puede conectar) 

            sum + = max (num [i], pre + left1); 

        } 

        if (k == 0 ) printf ( " % d \ n " , pre);               // k == 0, que es el primer "continuo 1 

        " sino   printf ( " % d \ n " , sum); 

    } 

    return  0 ; 

}

 

Supongo que te gusta

Origin www.cnblogs.com/LightyaChoo/p/12716561.html
Recomendado
Clasificación