Algorithm 动态规划-确定状态

Algorithm 动态规划-确定状态,algorithm,dynamic,state,dynamic-programming,Algorithm,Dynamic,State,Dynamic Programming,我最近在一门动态编程课程中遇到了这个问题,老实说,我不知道如何确定合适的状态 首先,我建议您构建递归方法 从变体中选择最佳:从段落或图开始 在每个步骤中,从可能的变体中选择最佳:添加分页符、添加下一个数字、添加下一个段落。简单的状态机有助于消除禁止的变体(例如,行中有2个分页符),但这不是必需的 当检查递归解时,您可以将其转换为自顶向下或自下而上的动态规划,如大多数关于DP的算法课程所述。作为当前页面p的DP状态,您可以使用数组(大小L*2),根据第P页上为数字保留的行数编制索引,从第P+1页引

我最近在一门动态编程课程中遇到了这个问题,老实说,我不知道如何确定合适的状态


首先,我建议您构建递归方法

从变体中选择最佳:从段落或图开始

在每个步骤中,从可能的变体中选择最佳:添加分页符、添加下一个数字、添加下一个段落。简单的状态机有助于消除禁止的变体(例如,行中有2个分页符),但这不是必需的


当检查递归解时,您可以将其转换为自顶向下或自下而上的动态规划,如大多数关于DP的算法课程所述。

作为当前页面p的DP状态,您可以使用数组(大小L*2),根据第P页上为数字保留的行数编制索引,从第P+1页引用,或(否定)第P+1页上为数字所需的行数,从第P页引用

每个数组元素由两个值组成:

  • x第1.P页上的段落数
  • DP算法完成后恢复段落/图形分布所需的一些数据
  • 使用此数组计算下一页(p+1)的数组。对于数组p的每个有效元素,添加新段落(x+1,x+2,…)到第P+1页,更新数组P+1的对应元素。如果可能,将这些段落引用的数字放在第P页,然后放在第P+1页,然后放在第P+2页。用较高的值覆盖数组P+1的元素,其值较低x


    该算法的时间复杂度为O(L*N):每页行数乘以段落数。因为处理每页是O(每页行数*每页平均段落数)。

    通常的问题是,您必须对段落p和图p进行重新排序(p,F)顺序或(F,p)顺序

    放在文档中的是(P1,F1),(P2,F2),(P3,F3),其中每个元组(p,F)可以是任意顺序(p,F)或(F,p),并且有些F-s的长度为0,这意味着没有F

    问题是找到每个(p,F)对的顺序

    找到最少paige数的一个解决方案是应用此规则

    lines_total = MIN(lines(P,F),lines(F,P)) + remaining() //this is custom addition
    
    好的,这个函数缺少原型,但是对于C来说

    calc_spend_lines(pfpairs * pairs)
    
    pfpaires在哪里

    typedef struct
    {
       int P;
       int F;
    } pfpaires;
    
    你们知道当p为0时,你们到达了终点

    您所要做的就是创建函数,实现特殊的+符号,并记住换页符和死线

    这就给出了O(N)解,对于最小超过页数而不是行数,因为结束条件是0

    如果您想最小化过多的行数,您可以使用二分法,将结束条件设置为其他值,而不是0,这将为您提供

    O(N*log(L))溶液

    编辑

    因为在当前的P和F之间可能有其他的P,我们只需要检查而不是((F,P),(P,F))也检查空白页(N),所以组合是((P,F)(P,N,F),(F,P),(F,N,P))结论是,算法更复杂,但复杂度相同。要点是,一旦您检查了4种排序中的一种,就只有一种简单的方法来进行最佳定位,只是当前状态(行)有点复杂。

    可以优化,但它是有效的解决方案: public class ParagraphsAndFigures {

            public static ArrayList<PageContent> generatePages(List<Paragraph> paragraphs, int L) {
                ArrayList<PageContent> pages = new ArrayList<PageContent>();
                for (int i = 0; i < paragraphs.size() * 2; i++) {
                    pages.add(new PageContent());
                }
                int page = 0;
    
                for (Paragraph paragraph : paragraphs) {
                    do {
                        int cur = pages.get(page).linesReserved;
                        int next = pages.get(page + 1).linesReserved;
    
                        if (cur + paragraph.size < L) {
                            cur += paragraph.size;
    
                            if (paragraph.figure != null) {
    
                                if (pages.get(page + 1).hasPicture()) {
                                    if (next + paragraph.figure.size < L) {
                                        pages.get(page).texts.add(paragraph);
                                        pages.get(page + 1).texts.add(paragraph.figure);
                                        pages.get(page).linesReserved += paragraph.size;
                                        pages.get(page + 1).linesReserved += paragraph.figure.size;
                                        break; // next paragraph
                                    } else {
                                        page++;
                                        continue;
                                    }
                                }
    
                                if (pages.get(page).hasPicture()) {
                                    if (cur + paragraph.figure.size < L) {
                                        pages.get(page).texts.add(paragraph);
                                        pages.get(page).texts.add(paragraph.figure);
                                        pages.get(page).linesReserved += paragraph.size;
                                        pages.get(page).linesReserved += paragraph.figure.size;
                                        break; // next paragraph
                                    } else {
                                        if (next + paragraph.figure.size < L) {
                                            pages.get(page).texts.add(paragraph);
                                            pages.get(page + 1).texts.add(paragraph.figure);
                                            pages.get(page).linesReserved += paragraph.size;
                                            pages.get(page + 1).linesReserved += paragraph.figure.size;
                                            break; // next paragraph
                                        }
                                        page++;
                                        continue;
                                    }
                                }
    
                                if (page != 0 && pages.get(page - 1).hasPicture()) {
                                    int prev = pages.get(page - 1).linesReserved;
                                    if (prev + paragraph.figure.size < L) {
                                        pages.get(page).texts.add(paragraph);
                                        pages.get(page - 1).texts.add(paragraph.figure);
                                        pages.get(page).linesReserved += paragraph.size;
                                        pages.get(page - 1).linesReserved += paragraph.figure.size;
                                        break; // next paragraph
                                    } else {
                                        if (cur + paragraph.figure.size < L) {
                                            pages.get(page).texts.add(paragraph);
                                            pages.get(page).texts.add(paragraph.figure);
                                            pages.get(page).linesReserved += paragraph.size;
                                            pages.get(page).linesReserved += paragraph.figure.size;
                                            break; // next paragraph
                                        }
                                        if (next + paragraph.figure.size < L) {
                                            pages.get(page).texts.add(paragraph);
                                            pages.get(page + 1).texts.add(paragraph.figure);
                                            pages.get(page).linesReserved += paragraph.size;
                                            pages.get(page + 1).linesReserved += paragraph.figure.size;
                                            break; // next paragraph
                                        }
                                        page++;
                                    }
                                }
    
                                if (page != 0) {
                                    int prev = pages.get(page - 1).linesReserved;
                                    if ( prev + paragraph.figure.size < L) {
                                        pages.get(page).texts.add(paragraph);
                                        pages.get(page - 1).texts.add(paragraph.figure);
                                        pages.get(page).linesReserved += paragraph.size;
                                        pages.get(page - 1).linesReserved += paragraph.figure.size;
                                        break; // next paragraph
                                    }
                                }
    
                                if (cur + paragraph.figure.size < L) {
                                    pages.get(page).texts.add(paragraph);
                                    pages.get(page).texts.add(paragraph.figure);
                                    pages.get(page).linesReserved += paragraph.size;
                                    pages.get(page).linesReserved += paragraph.figure.size;
                                    break; // next paragraph
                                }
    
                                if (next + paragraph.figure.size < L) {
                                    pages.get(page).texts.add(paragraph);
                                    pages.get(page + 1).texts.add(paragraph.figure);
                                    pages.get(page).linesReserved += paragraph.size;
                                    pages.get(page + 1).linesReserved += paragraph.figure.size;
                                    break; // next paragraph
                                }
                                page++;
                            }
                        }
                        page++;
                    } while (true);
                }
                return pages;
            }
        }
    
    公开课段落和人物{

    public class ParagraphsAndFiguresTest { @Test public void pageGeneration1() throws Exception { // given ArrayList paragraphs = new ArrayList(); paragraphs.add(new Paragraph(20,21)); paragraphs.add(new Paragraph(22,23)); paragraphs.add(new Paragraph(24,25));

                // when
                ArrayList<PageContent> pageContents = ParagraphsAndFigures.generatePages(paragraphs, 50);
                // then
                assertThat(transformToList(pageContents), is(asList("20", "21", "p0" ,"22" ,"23", "p1" ,"24" ,"25", "p2")));
            }
    
            @Test
            public void pageGeneration2() throws Exception {
                // given
                ArrayList<Paragraph> paragraphs = new ArrayList<Paragraph>();
                paragraphs.add(new Paragraph(10,11));
                paragraphs.add(new Paragraph(28,21));
                paragraphs.add(new Paragraph(22,23));
    
                // when
                ArrayList<PageContent> pageContents = ParagraphsAndFigures.generatePages(paragraphs, 50);
                // then
                assertThat(transformToList(pageContents), is(asList("10", "11" ,"28", "p0" ,"21", "22" , "p1" ,"23", "p2")));
            }
    
            @Test
            public void pageGeneration3() throws Exception {
                // given
                ArrayList<Paragraph> paragraphs = new ArrayList<Paragraph>();
                paragraphs.add(new Paragraph(10,11));
                paragraphs.add(new Paragraph(12,30));
                paragraphs.add(new Paragraph(13,19));
    
                // when
                ArrayList<PageContent> pageContents = ParagraphsAndFigures.generatePages(paragraphs, 50);
                // then
                assertThat(transformToList(pageContents), is(asList("10", "11" ,"12", "13", "p0" ,"30", "19" , "p1" )));
            }
    
            @Test
            public void pageGeneration4() throws Exception {
                // given
                ArrayList<Paragraph> paragraphs = new ArrayList<Paragraph>();
                paragraphs.add(new Paragraph(10,11));
                paragraphs.add(new Paragraph(30,12));
                paragraphs.add(new Paragraph(13,16));
    
                // when
                ArrayList<PageContent> pageContents = ParagraphsAndFigures.generatePages(paragraphs, 50);
                // then
                assertThat(transformToList(pageContents), is(asList("10", "11" ,"12", "16", "p0" ,"30", "13" ,"p1" )));
            }
    
            @Test
            public void pageGeneration5() throws Exception {
                // given
                ArrayList<Paragraph> paragraphs = new ArrayList<Paragraph>();
                paragraphs.add(new Paragraph(31,32));
                paragraphs.add(new Paragraph(17,21));
                paragraphs.add(new Paragraph(30,35));
    
                // when
                ArrayList<PageContent> pageContents = ParagraphsAndFigures.generatePages(paragraphs, 50);
                // then
                assertThat(transformToList(pageContents), is(asList("31", "p0", "32", "17", "p1", "21", "p2", "30", "p3", "35", "p4")));
            }
    
            private List<String> transformToList(ArrayList<PageContent> pageContents) {
                List<String> result = new ArrayList<String>();
                for (int i = 0; i < pageContents.size(); i++) {
                    PageContent pageContent = pageContents.get(i);
                    if (!pageContent.texts.isEmpty()) {
                        for (Text text : pageContent.texts) {
                            result.add(String.valueOf(text.size));
                        }
                        result.add("p"+i);
                    }
                }
                return result;
            }
        }
    
    publicstaticarraylistgeneratepages(列出段落,int-L){
    ArrayList pages=新建ArrayList();
    对于(int i=0;i