繁体   English   中英

最长单调子序列算法不是最长递增算法

[英]Longest monotonic subsequence algorithm NOT longest increasing algorithm

我在输入中有一些数字:

1 1 7 3 2 0 0 4 5 5 6 2 1

我寻找最长的单调子序列以及这个子序列的总和是多少。 结果是:

6 20

我在互联网上找不到算法。 你拥有/找到一个吗? 这是关于最长的单调而不是最长的递增子序列。

单调的定义: http : //en.wikipedia.org/wiki/Monotonic_function

我知道有人会问:你试过什么? 所以我试着写它(请不要检查它我只发布它所以没有人问上面的问题我寻找不同的算法->最佳算法)

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Rozwiazanie {
    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

            //2^63 > 10^16 = 10^7 * 10^9 longi starcza
            //10^9 inty starcza
            //int 32 bity, long 64 bity
            long podsuma = 0;
            int dlugosc = 0;
            int maxDlugosc = 0;
            long maxPodsuma = 0;
            int poczatekRownych = 0;
            int poprzedniWyraz = 0, aktualnyWyraz;//uwaga jakby cos nie gralo w sprawdzarce zmien typ na long
            boolean czyRosnacy = false, rowny = false;
            String[] splittedLinia = br.readLine().split((char) 32 + "");//moglaby byc " " ale tak na wszelki wypadek nie ma chuja zeby sie popierdolilo teraz nawet na linuxie
            for (int i = 0; i < splittedLinia.length; i++) {
                if (i == 0) {
                    aktualnyWyraz = Integer.parseInt(splittedLinia[0]);
                    maxDlugosc = dlugosc = 1;
                    maxPodsuma = podsuma = aktualnyWyraz;
                    if (splittedLinia.length > 1) {
                        int nastepnyWyraz = Integer.parseInt(splittedLinia[1]);
                        czyRosnacy = nastepnyWyraz > aktualnyWyraz;
                        rowny = nastepnyWyraz == aktualnyWyraz;
                    }
                    System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 1);
                } else {
                    aktualnyWyraz = Integer.parseInt(splittedLinia[i]);
                    System.out.println(rowny);
                    if (aktualnyWyraz == poprzedniWyraz && rowny) {
                        podsuma += aktualnyWyraz;
                        dlugosc++;
                        System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 2);
                    } else if (rowny) {
                        rowny = false;
                        czyRosnacy = aktualnyWyraz > poprzedniWyraz;
                        System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 3);
                    }

                    if (!rowny) {

                        if (aktualnyWyraz >= poprzedniWyraz && czyRosnacy) {
                            podsuma += aktualnyWyraz;
                            dlugosc++;
                            System.out.println("akt:" + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 4);
                        } else if (aktualnyWyraz <= poprzedniWyraz && !czyRosnacy) {
                            podsuma += aktualnyWyraz;
                            dlugosc++;
                            System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 5);
                        } else {
                            //  if (aktualnyWyraz == poprzedniWyraz) {
                            rowny = true;
                            //  } else {
                            if (maxDlugosc < dlugosc) {
                                maxDlugosc = dlugosc;
                                maxPodsuma = podsuma;

                            }
                            podsuma = poprzedniWyraz + aktualnyWyraz;
                            dlugosc = 2;
                            czyRosnacy = aktualnyWyraz > poprzedniWyraz;
                            rowny = aktualnyWyraz == poprzedniWyraz;
                            System.out.println("akt: " + aktualnyWyraz + " pop: " + poprzedniWyraz + " dlugosc: " + dlugosc + " " + 6);
                            //}
                        }
                    }
                }
                poprzedniWyraz = aktualnyWyraz;
            }
            System.out.println(maxDlugosc + " " + maxPodsuma);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//65 87 47 5 12 74 25 32 78 44 40 77 85 4 29 57:

试试这个:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Rozwiazanie {
    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String[] splittedLinia = br.readLine().split((char) 32 + "");//moglaby byc " " ale tak na wszelki wypadek nie ma chuja zeby sie popierdolilo teraz nawet na linuxie
            int aktualnyWyraz = Integer.parseInt(splittedLinia[0]);//uwaga jakby cos nie gralo w sprawdzarce zmien typ na long
            int poprzedniWyraz = 0; 

            long podsumaRosnaca = aktualnyWyraz;
            long podsumaSpadajaca = aktualnyWyraz;

            int dlugoscRosnaca = 1;
            int dlugoscSpadajaca = 1;

            int maxDlugosc = 1;
            long maxPodsuma = aktualnyWyraz;

            int czyRosnacy = 0; // 0 -- nie znane (jezeli w poczatku wszystkie liczby sa rowne), 1 -- rosnacy, -1 -- spadajacy
            boolean rowny = false;
            System.out.println("akt: " + aktualnyWyraz + " dlR: " + dlugoscRosnaca + " podsumaR: " + podsumaRosnaca + " dlP: " + dlugoscSpadajaca + " podsumaP: " + podsumaSpadajaca);

            for (int i = 1; i < splittedLinia.length; i++) {
                poprzedniWyraz = aktualnyWyraz;
                aktualnyWyraz = Integer.parseInt(splittedLinia[i]);
                if (aktualnyWyraz == poprzedniWyraz) {
                    podsumaRosnaca += aktualnyWyraz;
                    podsumaSpadajaca += aktualnyWyraz;
                    dlugoscRosnaca++;
                    dlugoscSpadajaca++;
                    rowny = true;
                } else { // rozne liczby
                    if (aktualnyWyraz > poprzedniWyraz) { // rosnie
                        podsumaRosnaca += aktualnyWyraz;
                        dlugoscRosnaca++;      

                        if (rowny) {
                            dlugoscSpadajaca = 1;
                            podsumaSpadajaca = 0;
                            rowny = false;
                        }       
                        if (czyRosnacy < 0) {
                            if (dlugoscSpadajaca > maxDlugosc) {
                                maxDlugosc = dlugoscSpadajaca;
                                maxPodsuma = podsumaSpadajaca;
                            }
                            podsumaSpadajaca = 0;
                            dlugoscSpadajaca = 1;
                        }
                        czyRosnacy = 1;   
                    } else { // spada
                        podsumaSpadajaca += aktualnyWyraz;
                        dlugoscSpadajaca++; 

                        if (rowny) {
                            dlugoscRosnaca = 1;
                            podsumaRosnaca = 0;
                            rowny = false;
                        }
                        if (czyRosnacy == 1) {
                            if (dlugoscRosnaca > maxDlugosc) {
                                maxDlugosc = dlugoscRosnaca;
                                maxPodsuma = podsumaRosnaca;
                            }
                            podsumaRosnaca = 0;
                            dlugoscRosnaca = 1;
                        }  
                        czyRosnacy = -1;
                    }

                }
                System.out.println("akt: " + aktualnyWyraz + " dlR: " + dlugoscRosnaca + " podsumaR: " + podsumaRosnaca + " dlP: " + dlugoscSpadajaca + " podsumaP: " + podsumaSpadajaca);
            }


            System.out.println("maxDlugosc " + maxDlugosc + " maxPodsuma " + maxPodsuma);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我必须改变的:

  • 您需要一个计数器 [dlugosc] (+ sum [podsuma]) 用于升序 [rosnacy] 和降序 [spadajacy] 值,因为当值相同 [rowny] 时,您需要对两者进行计数。
  • 我将布尔值“rowny”[equal] 更改为 int,因为我认为有 3 个可能的值:升序、降序或未知。 如果一开始有几个相等的值,那么总是“未知”。
  • 该程序至少需要一个数字,但因此无论 i == 0 与否,您都不需要检查循环的每次迭代。
  • 通过数字,我必须检查几件事,最重要的是,实际值 [aktualnyWyraz] 和上次使用的值 [poprzedniWyraz] 是否相同(然后所有计数器和总和都必须更改)或不同。 不同可能意味着升序或降序,因此我们必须增加相关计数器并总结相关总和。 “相反”变量会发生什么? 好吧,我们需要检查计数器是否大于最大值(因此这些值可能对结果有用),然后将它们重新设置为起始值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM