【问题标题】:dynamic programming for minimum cost of breaking the string动态规划,以最小的破坏字符串的成本
【发布时间】:2013-11-09 01:45:28
【问题描述】:

某种字符串处理语言提供了一种将字符串分成两部分的原始操作。由于此操作涉及复制原始字符串,因此无论剪切的位置如何,长度为 n 的字符串都需要 n 个单位的时间。现在假设你想把一个字符串分成很多块。休息的顺序会影响总运行时间。例如,如果您想在位置 3 和 10 剪切一个 20 个字符的字符串,那么在位置 3 进行第一次剪切会产生 20+17=37 的总成本,而首先执行位置 10 的成本会更好 20+ 10=30。

给出一个动态规划算法,给定长度为 n 的字符串中 m 个切割的位置,找到将字符串分成 m + 1 段的最小成本。

这个问题来自“算法”第6章6.9。

由于这个问题没有答案,这就是我的想法。

OPT(i,j,n) 定义为断开字符串的最低成本,i 为开始索引,j 为字符串的结束索引,n 为我可以使用的剩余剪切数。

这是我得到的:

OPT(i,j,n) = min {OPT(i,k,w) + OPT(k+1,j,n-w) + j-i} for i<=k<j and 0<=w<=n

对还是错?请帮忙,谢谢!

【问题讨论】:

  • 实现并测试它?
  • 提示:你需要n参数吗? :)
  • @j_random_hacker 这件事真的困扰了我好几天..我不明白为什么不需要n参数..如果你知道答案,请告诉我,谢谢!
  • 我明白为什么我的解释让你感到困惑了!不要使用 i 和 j 作为字符串中的索引(位置),而是将它们视为 块编号。字符串中有 m+1 个块,由您需要进行的 m 个切割定义。例如。在示例中,有 3 个块:1-3、4-10 和 11-20(假设“在位置 3 切割”表示“在位置 3 之后切割”)。
  • 提示:它涉及到每个块的结束位置(或开始位置)的数组。

标签: string algorithm dynamic-programming


【解决方案1】:

我认为你的循环关系可以变得更好。这是我想出的,将 cost(i,j) 定义为将字符串从索引 i 剪切到 j 的成本。那么,

cost(i,j) = min {length of substring + cost(i,k) + cost(k,j) where i < k < j}

【讨论】:

    【解决方案2】:
     void  s_cut()    
      {
        int l,p;
        int temp=0;
        //ArrayList<Integer> al = new ArrayList<Integer>();
        int al[];
        Scanner s=new Scanner(System.in);
        int table[][];
        ArrayList<Integer> values[][];
        int low=0,high=0;
        int min=0;
    
        l=s.nextInt();
        p=s.nextInt();
    
        System.out.println("The values are "+l+"  "+p);
    
        table= new int[l+1][l+1];
        values= new ArrayList[l+1][l+1];
        al= new int[p];
    
        for(int i=0;i<p;i++)
        {
            al[i]=s.nextInt();
    
        }
    
        for(int i=0;i<=l;i++)
        for(int j=0;j<=l;j++)
            values[i][j]=new ArrayList<Integer>();
    
        System.out.println();
    
        for(int i=1;i<=l;i++)
            table[i][i]=0;
        //Arrays.s
        Arrays.sort(al);
    
        for(int i=0;i<p;i++)
        {
            System.out.print(al[i]+ "  ");
    
        }
    
    
        for(int len=2;len<=l;len++)
        {
            //System.out.println("The length is  "+len);
    
            for(int i=1,j=i+len-1;j<=l;i++,j++)
            {
    
                high= min_index(al,j-1);
                low= max_index(al,i);
    
                System.out.println("Indices are "+low+"  "+high);
    
                if(low<=high && low!=-1 && high!=-1)
                {
    
                int cost=Integer.MAX_VALUE;;
    
                for(int k=low;k<=high;k++)
                {
                    //if(al[k]!=j)
                    temp=cost;
                    cost=Math.min(cost, table[i][al[k]]+table[al[k]+1][j]);
    
                    if(temp!=cost)
                    {
                        min=k; 
                        //values[i][j].add(al[k]);
                        //values[i][j].addAll(values[i][al[k]]);
                        //values[i][j].addAll(values[al[k]+1][j]);
                        //values[i][j].addAll(values[i][al[k]]);
                    }
    
                    //else
                    //cost=0;
                }
    
                table[i][j]= len+cost;
    
                values[i][j].add(al[min]);
                //values[i][j].addAll(values[i][al[min]]);
                values[i][j].addAll(values[al[min]+1][j]);
                values[i][j].addAll(values[i][al[min]]);
    
                }
    
                else
                    table[i][j]=0;
    
                System.out.println(" values are "+i+"  "+j+"  "+table[i][j]);
            }
        }
    
        System.out.println(" The minimum cost is "+table[1][l]);
    
        //temp=values[1][l];
        for(int e: values[1][l])
        {
            System.out.print(e+"-->");
    
        }
    
    }
    

    上述方案的复杂度为O(n^3)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-01
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      • 1970-01-01
      相关资源
      最近更新 更多