我该如何处理这个C​​ombinatorics Fence-Paint算法?

时间:2016-12-13 19:53:12

标签: algorithm

我在lintcode上坚持这个问题,而且我已经阅读了两个过去的解决方案,但这些解决方案对我来说都没有意义。

问题如下:

There is a fence with n posts, each post can be painted with one of the k colors.
You have to paint all the posts such that no more than two adjacent fence posts have the same color.
Return the total number of ways you can paint the fence.

给定n = 3,k = 2,返回6.

所以我明白的部分是,如果n = 0(我们有0个帖子)或k = 0(我们有0个颜料),我们不能画任何东西所以返回0

如果n == 1,帖子可以用K方式绘制,所以返回k

当n为2时,如果相邻的帖子相等,我们可以用K * 1方式绘制它,如果相邻的帖子不同,我们可以用K *(K-1)方式绘制它。

如果n == 3或更多:相同的相邻颜色将是:K * 1 * K-1 * 1 * K-1 ... 不同的是:K * K-1 * K-1 ....

我如何从这里开始?我已经看到一个人再次创建一个带有[0,k,2k和0]的矩阵,另一个人简化了不同的颜色"至(k + k *(k-1))*(k-1)但我不知道他们中的任何一个如何跳到他们结论的那一步

编辑:一个人解决方案如下:

class Solution:
# @param {int} n non-negative integer, n posts
# @param {int} k non-negative integer, k colors
# @return {int} an integer, the total number of ways
def numWays(self, n, k):
    # Write your code here
    table = [0, k, k*k, 0]

    if n <= 2:
        return table[n]

    # recurrence equation
    # table[posts] = (color - 1) * (table[posts - 1] + table[posts - 2])
    for i in range(3, n + 1):
        table[3] = (k - 1) * (table[1] + table[2])
        table[1], table[2] = table[2], table[3]

    return table[3]

但是我不明白为什么他在桌子末尾有[0],以及他如何建立递归方程

3 个答案:

答案 0 :(得分:1)

此问题最困难的部分是设置递归。令L为返回给定n个帖子和k个颜色的组合数量的函数。然后有两种情况需要考虑:

一个。添加两个相同颜色的帖子:

  

L(n + 2,k)=(k-1)* L(n,k)

湾添加两个不同颜色的帖子:

  

L(n + 1,k)=(k-1)* L(n,k)

给出了论坛:

  

L(n,k)=(k-1)*(L(n-1,k)+ L(n-2,k))

示例

对于n = 3和k = 2,假设我们知道前两个帖子的组合数量

  

n = 1 | k = 2

     

n = 2 | k * k = 4

现在要解决n = 3我们需要使用相邻n = 2且n = 3的预先计算的值

一个。不同的颜色:通过添加一个不同于尾随的帖子,sum [2] *(k-1)= 4

湾相同颜色:退回一个瓷砖并添加两个相同颜色而不是n = 1,这得到sum [1] *(k-1)= 2

至于矩阵,它是一个品味问题,像current和prev这样的变量也会很好。

答案 1 :(得分:0)

对于没有相邻的相同颜色的帖子,你有第一篇帖子的k选项,每个额外帖子有k-1,所以k *(k-1)^(n-1)。

对于一次重复,计算放置n-1的方式的数量,然后乘以(n-1)以考虑重复的帖子(重复该帖子),因此k *(k-1)^(n -2)*(n-1)

总和是你的答案。

k * (k-1)^(n-1) + k * (k-1)^(n-2) * (n-1)

答案 2 :(得分:0)

根据Dominik G的回答,可以给出一个明确的公式 L(n,k)因为固定的k是一个 constant recursive sequence

我的结果是k >= 2D = sqrt((k+1)^2 - 4)u = (k-1+D)/2 v = (k-1-D)/2x^2 = (k-1)(x + 1)是两种解决方案 二次方程n >= 1,然后有L(n, k) = (k/(k-1))*((u^(n+1)-v^(n+1))/D

var getDateTimeStr = function(hours){
  //create a string of the date and time 30 days ago
  var ts = new Date().getTime();
  var tsYest = (ts - (hours /*hrs in 30 days*/ * 3600) * 1000);
  var d = new Date(tsYest);
  var yestDateStr = d.getFullYear() + '/'
  + ('0' + (d.getMonth()+1)).slice(-2) + '/'
  + ('0' + d.getDate()).slice(-2) + ' '
  + ('0' + (d.getHours()+1)).slice(-2) + ':'
  + ('0' + (d.getMinutes()+1)).slice(-2) + ':'
  + ('0' + (d.getSeconds()+1)).slice(-2);
  console.log(yestDateStr);
  return yestDateStr;
}

//PARAMETERS FOR 3 RANGES
var params1 = {
  TableName: "O2Sensor_data",
  ConsistenRead: false,
  ScanindexForward: true,
  KeyConditionExpression: "sensor_id = :sensor AND #dtdt >= :start_date",
  ExpressionAttributeNames: {
  "#dtdt": "DateTime"
},
  ExpressionAttributeValues: {
    ":sensor": "sensor1",
    ":start_date": getDateTimeStr(720)
  }
}

var params2 = {
  TableName: "O2Sensor_data",
  ConsistenRead: false,
  ScanindexForward: true,
  KeyConditionExpression: "sensor_id = :sensor AND #dtdt >= :start_date",
  ExpressionAttributeNames: {
    "#dtdt": "DateTime"
  },
  ExpressionAttributeValues: {
    ":sensor": "sensor1",
    ":start_date": getDateTimeStr(168)
  }
}

var params3 = {
  TableName: "O2Sensor_data",
  ConsistenRead: false,
  ScanindexForward: true,
  KeyConditionExpression: "sensor_id = :sensor AND #dtdt >= :start_date",
  ExpressionAttributeNames: {
    "#dtdt": "DateTime"
  },
  ExpressionAttributeValues: {
    ":sensor": "sensor1",
    ":start_date": getDateTimeStr(24)
  }
}

//DYNAMODB QUERY FUNCTION
function chartCreate(params, color){
    console.log("Querying DynamoDB");
    docClient.query(params, function(err, data){
      if(err) console.log(err, err.stack);
      else{
        DateTimeArr = [];
        o2readingArr = [];
        data.Items.forEach(function(item){
          DateTimeArr.push(item.DateTime.toString());
          o2readingArr.push(item.o2percent.toString());
  });

      var dataMap = {
        type: 'line',
        data: {//displays readings form sensor based on the range selected
          labels: DateTimeArr,
          datasets: [{
            label: '% O2 In Air',
            data: o2readingArr,
            backgroundColor: color
          },
          {//creates a line at 19.5% to see if data readings are below safe         value
            label: "19.5%",
            data: Array.apply(null, new  Array(o2readingArr.length)).map(Number.prototype.valueOf, 19.5),
            fill: false,
            radius: 0,
            borderColor: "rgba(0,0,0,.5)"
          }]//end of datasets
        },
        options: {
          animation: false,
          responsive: true,
          scaleOverride: true
        }
      };//end of dataMap var declaration

      //CREATE CHART
      var ctx = document.getElementById("lineChart").getContext("2d");
        ctx.canvas.width = 600;
        ctx.canvas.height = 256;
      window.datChart = new Chart(ctx, dataMap);
    }//end of else statement
  });//end of query function
}

function chartUpdate(params){
  console.log("Querying DynamoDB");
  docClient.query(params, function(err, data){
    if(err) console.log(err, err.stack);
    else{
      data.Items.forEach(function(item){
        DateTimeArr.push(item.DateTime.toString());
        o2readingArr.push(item.o2percent.toString());
       });
    }
  });
}

function chooseChart(){
  if(window.datChart){window.datChart.destroy();}
  if(document.getElementById("sel1").value == "last30"){
    currParams = params1;
    currColor = "rgba(0,0,255,.8)";
    chartCreate(params1, "rgba(0,0,255,.8)");
  }//blue
  else if(document.getElementById("sel1").value == "last7"){
    currParams = params2;
    currColor = "rgba(0,255,0,.8)";
    chartCreate(params2, "rgba(0,255,0,.8)");
  }//green
  else if(document.getElementById("sel1").value == "last24"){
    currParams = params3;
    currColor = "rgba(255,0,0,.8)";
    chartCreate(params3, "rgba(255,0,0,.8)");
  }//red
  else{console.log("something went wrong in chooseChart function");}
}

chooseChart();

setInterval(function(){
  window.datChart.destroy();
  chartUpdate(currParams);
  window.datChart.update();
}, 5000);

如果能够充分计算,这将成为一种快速算法 浮点精度。

嗯,我担心乳胶格式在这里不起作用,但公式很容易理解