【问题标题】:Minimum cost to convert a string to other将字符串转换为其他字符串的最低成本
【发布时间】:2015-05-25 08:30:24
【问题描述】:

给定 2 个长度相同的字符串 A 和 B。A 包含 '0'、'1' 和 '?'; B 仅包含“0”和“1”。我们需要通过对字符串 A 执行一系列允许的操作来找到将 A 转换为 B 的最小成本。

允许以下操作:

  1. 用成本 x 将“0”更改为“1”
  2. 将“1”更改为“0”,成本为 y
  3. 更改“?”成本为 z 的“0”或“1”
  4. 用成本 t 交换两个相邻的字符。

我们需要找到最低成本。

示例:令 N=6 , x=1 , y=1000 , z=1 , t=1 , A=01??00 和 B=001010 则答案为 4。

如何使用动态规划解决这个问题?有什么可以复发的吗?请帮忙

【问题讨论】:

  • 预期的时间复杂度(或约束条件)是多少?
  • @kraskevich 1 ≤ N ≤ 2000 和 1 ≤ x, y, z, t ≤ 1000 。 z ≤ min(x, y) 所以 O(N^2) 也可以工作

标签: string algorithm recursion dynamic-programming


【解决方案1】:

让我们从一些观察开始:

  1. 如果我们匹配两个字符串中的所有字符串,则会自动匹配零。

  2. 操作顺序无关紧要。也就是说,我们可以假设我们首先进行所有更改(0 到 1、1 到 0 或 ? 到某事),然后执行所有交换。

  3. 假设第一个字符串中 1 的位置是 (p_1, p_2, ..., p_n),而在第二个字符串中它们是 (q_1, q_2, ..., q_n)。然后,如果我们将pq 按排序顺序匹配,我们就会最小化交换成本。

  4. 让我们看看ii + 1的位置。让我们将balance[i]定义为长度为i + 1的前缀中ab的个数之差。那么恰好balance[i] swaps 将触及这两个元素。第 3 步暗示了此声明。

  5. 所有这些观察导致以下动态规划解决方案:状态为(prefix length, current balance)。该值是处理给定长度的前缀以使余额等于指定值的最小成本。有O(N ^ 2) 个状态。如何进行过渡?我们可以尝试将所有内容放在a 的当前位置并适当地计算成本。

  6. 答案是f(N, 0)

这里有一些代码:

public class Task {

    final int INF = 1_000_000_000;

    int cost01;
    int cost10;
    int costUnknown;
    int costSwap;

    int getDeltaBalance(int c1, int c2) {
        return c1 - c2;
    }

    int getCost(char start, int want) {
        if (start == '?')
            return costUnknown;
        if (start - '0' == want)
            return 0;
        if (start == '1')
            return cost10;
        return cost01;
    }

    public void solve(Scanner in, PrintWriter out) throws IOException {
        int n = in.nextInt();
        cost01 = in.nextInt();
        cost10 = in.nextInt();
        costUnknown = in.nextInt();
        costSwap = in.nextInt();
        String a = in.next();
        String b = in.next();
        int[][] dp = new int[n + 1][2 * n + 1];
        for (int i = 0; i <= n; i++) {
            Arrays.fill(dp[i], INF);
        }
        dp[0][n] = 0;
        for (int pos = 0; pos < n; pos++) {
            for (int balance = -n; balance <= n; balance++) {
                for (int curNumber = 0; curNumber <= 1; curNumber++) {
                    int newBalance = balance + getDeltaBalance(curNumber, b.charAt(pos) - '0');
                    if (newBalance < -n || newBalance > n)
                        continue;
                    int newCost = dp[pos][balance + n] + costSwap * Math.abs(balance)
                            + getCost(a.charAt(pos), curNumber);
                    dp[pos + 1][newBalance + n] = Math.min(dp[pos + 1][newBalance + n], newCost);
                }
            }
        }
        out.println(dp[n][n]);
    }
}

【讨论】:

    【解决方案2】:

    ruby 代码大概是这样的。它将通过 ruby​​ 的少数在线挑战

    def abc
    u=gets.to_i
    val = []
    w=[]
    for i in (1..u)
    k=i+1
    k3=i+2
    costi = 0
    costk = 0
    costk3=0
    n, x, y, z, t= [gets.split.map(&:to_i)].first
    q = [x,y].min
    if (1..1000).include?(x) and (1..1000).include?(y) and (1..q).include?(z)  and (1..1000).include?(t)
    a=[gets.chomp.split(//)].first
    a.keep_if{|v| v == "0"|| v == "1" || v == "?"}
    a.keep_if{a.length == n}
    c=a.clone
    d=a.clone
    b=[gets.chomp.split(//)].first
    b.keep_if{|v| v == "0"|| v == "1"}
    b.keep_if{b.length == a.length}
    if b.length!=a.length
    break
    end 
    val.push(n)
    end
    end_val = val.sort
    count = (val.count*0.3).to_i
    if (1..2000).include?(val.inject(0,:+)) &&    end_val.first(count).inject(0,:+)<=25
    for p in (0..2)
    if p == 0
    m=a.length
    for l in (0..m-1)
    if a[l] != b[l]
       if a[l] == "0" 
         a[l] = "1"
         costi =  costi + x
      elsif a[l] == "1"
           a[l] = "0"
           costi = costi + y
      elsif a[l] == "?"
            a[l] = b[l]
            costi = costi + z
     end
    end
    end
    elsif p ==1
    m=a.length
    $m =m
    $i=0
    while $i < $m do
    if c[$i] != b[$i]
    if c[$i] == b[$i+1] && c[$i+1] == b[$i]     
        c[$i] = b[$i]
        c[$i+1] = b[$i+1] 
        costk =costk + t
        $i +=1
    elsif c[$i] == b[$i+1]
           e1 = c[$i+1] 
    
           c[$i+1] = c[$i]
    
           c[$i]=e1           
             costk =  costk + t
            if c[$i] == "?"
        c[$i] = b[$i]
        costk =  costk + z
        elsif c[$i] == "0"
      c[$i] = b[$i]
        costk =  costk + x
    elsif c[$i] == "1"
    c[$i] = b[$i]
        costk =  costk + y            
    end
    elsif c[$i+1] == b[$i]
         e2 = c[$i]  
    
     c[$i] = c[$i+i]
    
     c[$i+1]=e2
             costk =  costk + t
     if c[$i+1] == "?"
       c[$i+1] = b[$i+1]
        costk =  costk + z
     elsif c[$i+1] == "0"
      c[$i+1] = b[$i+1]
        costk =  costk + x
     elsif c[$i+1] == "1"
     c[$i+1] = b[$i+1]
        costk =  costk + y            
     end        
      elsif c[$i] == "?"
         c[$i] = b[$i]
        costk =  costk + z
     elsif c[$i] == "0"
      c[$i] = b[$i]
        costk =  costk + x
     elsif c[$i] == "1"
     c[$i] = b[$i]
        costk =  costk + y            
    end
    end
    $i +=1
    end
    elsif p==2
    m=a.length
    $m =m
    $i=$m-1
    while $i >=0 do
    if d[$i] != b[$i]
    if d[$i] == b[$i-1] && d[$i-1] == b[$i]     
        d[$i] = b[$i]
        d[$i-1] = b[$i-1] 
        costk3 =costk3 + t
        $i -=1
        elsif d[$i-1] == b[$i]
            e4 = d[$i] 
            d[$i] = d[$i-i]
         d[$i-1]=e4
             costk3 =  costk3 + t  
           if d[$i-1] == "?"
        d[$i-1] = b[$i-1]
        costk3 =  costk3 + z
        elsif d[$i-1] == "0"
        d[$i-1] = b[$i-1]
        costk3 =  costk3 + x
        elsif d[$i-1] == "1"
        d[$i-1] = b[$i-1]
        costk3 =  costk3 + y            
        end 
        elsif d[$i] == "?"
        d[$i] = b[$i]
        costk3 =  costk3 + z
        elsif d[$i] == "0"
        d[$i] = b[$i]
        costk3 =  costk3 + x
        elsif d[$i] == "1"
        d[$i] = b[$i]
        costk3 =  costk3 + y            
        end
        end
        $i -=1
        end
        end
        end
        end
        v =[ costi, costk,costk3].min
        w.push(v)
        end
        puts w
        return w
        end
        abc
    

    【讨论】:

      猜你喜欢
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-10
      • 1970-01-01
      • 2019-01-05
      • 2013-06-05
      相关资源
      最近更新 更多