Java 动态规划在图书复制中的应用

Java 动态规划在图书复制中的应用,java,algorithm,dynamic-programming,recurrence,Java,Algorithm,Dynamic Programming,Recurrence,我正在实现复制书籍问题的动态规划解决方案。该解决方案的思想来源于和 问题陈述: 在书籍印刷术发明之前,复印是很困难的 一本书。所有的内容都必须由所谓的 抄写员。抄写员得到一本书,几个月后 他完成了它的副本。一位最著名的抄写员住在伦敦 15世纪,他的名字是Xaverius Endricus Remius Ontius Xendrianus(施乐)。不管怎么说,这工作很烦人,也很无聊。及 加快速度的唯一办法是雇佣更多的抄写员 从前,有一个剧团想要演出 著名的古代悲剧。这些剧本分为三个部分 当然,许多

我正在实现复制书籍问题的动态规划解决方案。该解决方案的思想来源于和

问题陈述:

在书籍印刷术发明之前,复印是很困难的 一本书。所有的内容都必须由所谓的 抄写员。抄写员得到一本书,几个月后 他完成了它的副本。一位最著名的抄写员住在伦敦 15世纪,他的名字是Xaverius Endricus Remius Ontius Xendrianus(施乐)。不管怎么说,这工作很烦人,也很无聊。及 加快速度的唯一办法是雇佣更多的抄写员

从前,有一个剧团想要演出 著名的古代悲剧。这些剧本分为三个部分 当然,许多书和演员需要更多的拷贝。所以他们 雇了许多抄写员来抄写这些书。想象一下,你有我 可能有不同页数的书籍(编号为1、2、…、m) (p_1,p_2,…,p_m)并且您希望每一个都复制一份。
你的任务是把这些书分成k个抄写员,k不确定你的解决方案,但这里有一个直观的递归方法,可以记忆。假设有n本书,其中第i本书有页[i]页。也要有m订户。同样,如果我们只得到书籍i,i+1…..n并且只有j订阅者来做这项工作,那么让dp[i][j]成为问题的答案。下面是一个带记忆的递归伪代码

    //dp[][] is memset to -1 from main
    // Assuming books are numbered 1 to n
    // change value of MAX based on your constraints
    int MAX = 1000000000;
    int rec(int position , int sub )
    {
          // These two are the base cases
          if(position > n)
          {
             if(sub == 0)return 0;
             return MAX;
          }
          if(sub == 0)
          {
              if(position > n)return 0;
              return MAX;
          }

          // If answer is already computed for this state return it
          if(dp[position][sub] != -1)return dp[position][sub];

          int ans = MAX,i,sum = 0;
          for(i = position; i <= n;i++)
          {
             sum += pages[i];
             // taking the best of all possible solutions
             ans = min(ans,max(sum,rec(i+1,sub-1)));
          }
          dp[position][sub]=ans;
          return ans; 
    }

    //from main call rec(1,m) which is your answer
//dp[][]从main中被memset设置为-1
//假设书籍编号为1到n
//根据约束更改最大值
int MAX=100000000;
int rec(int位置,int接头)
{
//这两个是基本情况
如果(位置>n)
{
如果(sub==0)返回0;
返回最大值;
}
如果(sub==0)
{
如果(位置>n)返回0;
返回最大值;
}
//如果已经为此状态计算了答案,则返回它
如果(dp[position][sub]!=-1)返回dp[position][sub];
int ans=最大值,i,和=0;

对于(i=位置;i您的问题是什么?如果您将问题陈述包含在beginning@sasha问题在问题所附的超链接中提供。是的,阅读它知道你能告诉问题到底是什么吗?是在编码/查找测试用例解释/提出dp解决方案中。also一般来说,问题应该是独立的,没有链接,链接应该是供进一步参考或详细说明explanation@faizanjehangir超链接往往会消失。请在问题本身中发布问题陈述的简短解释。@amit我已经添加了关于问题陈述和问题本身的更多细节。你能解释一下吗e在本程序中使用
sub
?sub表示订阅人数position表示只考虑position中的book,position+1…n。参见我的dp[][]数组的定义,它解释了position(i)和sub(j)@faizanjehangir看看我的编辑,转到代码工作版本的链接索引有点混乱,但解决方案是完美的!
100 100 100 
300 300 300 
600 600 600 
1000 700 700 
1500 900 900 
2100 1100 1100 
2800 1300 1300 
3600 1500 1500 
4500 1700 1700 

100 100 100 100 
200 200 200 200 
300 300 300 300 
400 300 300 300 
500 300 300 300 
private void processScribes(){
        int[][] bookScribe = new int[numOfBooks][numOfScribes];
        //set first row to b1 page number
        for (int j = 0; j < numOfScribes; ++j)
            bookScribe[0][j] = bookPages[0];

        //set first column to sum of book page numbers
        for (int row = 1; row < numOfBooks; ++row)
            bookScribe[row][0] = bookScribe[row - 1][0] + bookPages[row]; 

        //calculate the kth scribe using dp
        for (int i = 1; i < numOfBooks; ++i){
            for (int j = 1; j < numOfScribes; ++j){
                //calculate minimum of maximum page numbers
                //from k = l + 1 to i
                //calculate sum 
                int minValue = 1000000;
                for (int k = 0; k < i - 1; ++k){
                    int prevValue = bookScribe[i - k][j - 1];
                    int max = 0;
                    int sumOflVals = 0;
                    for (int l = k + 1; l <= i; ++l){
                        sumOflVals = sumOflVals + bookPages[l];
                    }
                    if (prevValue > sumOflVals){
                        max = prevValue;
                    }
                    else
                        max = sumOflVals;
                    if (max < minValue )
                        minValue = max;
                }
                if (minValue == 1000000)
                    minValue = bookScribe[i][0];
                //store minvalue at [i][j]
                bookScribe[i][j] = minValue;
            }
        }

        //print bookScribes
        for (int i = 0; i < numOfBooks; ++i){
            for (int j = 0; j < numOfScribes; ++j)
                System.out.print(bookScribe[i][j] + " ");
            System.out.println();
        }
        System.out.println();
    }
    //dp[][] is memset to -1 from main
    // Assuming books are numbered 1 to n
    // change value of MAX based on your constraints
    int MAX = 1000000000;
    int rec(int position , int sub )
    {
          // These two are the base cases
          if(position > n)
          {
             if(sub == 0)return 0;
             return MAX;
          }
          if(sub == 0)
          {
              if(position > n)return 0;
              return MAX;
          }

          // If answer is already computed for this state return it
          if(dp[position][sub] != -1)return dp[position][sub];

          int ans = MAX,i,sum = 0;
          for(i = position; i <= n;i++)
          {
             sum += pages[i];
             // taking the best of all possible solutions
             ans = min(ans,max(sum,rec(i+1,sub-1)));
          }
          dp[position][sub]=ans;
          return ans; 
    }

    //from main call rec(1,m) which is your answer