TopCoder上的FlowerGarden prolble如何成为DP-one?

时间:2012-06-28 16:15:33

标签: algorithm dynamic-programming

我正在阅读Dumitru关于基于DP的问题here的优秀教程。我正在尝试针对1D DP问题列表中提到的FlowerGarden问题提出基于DP的方法。

我只能想到一个非DP解决方案,它将涉及最初按顺序对花进行排序,然后根据问题中提到的不同条件检查对它们进行重新排序。这不归类为DP,是吗?

社论也没有提到任何关于DP的事情。 任何人都可以指出一个基于DP的解决方案吗?

谢谢!

编辑:

我没有意识到该链接需要注册。这就是问题所在:

  

问题陈述          您正在种植带有灯泡的花园,全年为您提供欢乐的花朵。但是,你想要种花   这样当它们可见时它们不会阻挡其他花朵。

     

您将获得int []高度,int [] bloom和int [] wilt。   每种类型的花由相同指数的元素表示   高度,绽放和枯萎。高度代表每种类型的高度   花朵长大,花朵代表每种花朵的早晨   从地面弹出,枯萎代表每个人的夜晚   花的类型萎缩并死亡。每个元素都盛开,枯萎   将是1到365之间的数字,wilt [i]将永远   大于绽放[i]。你必须种植所有的花   相同类型的单行外观,你也想拥有   最高的花朵尽可能向前。但是,如果一朵花   type比其他类型高,两种类型都可以   在同一时间,必须在前面种植较短的花   更高的花,以防止阻塞。一朵花盛开   早上和晚上的枯萎,所以即使一朵花盛开   在同一天,另一朵花在枯萎,一朵可以挡住另一朵。

     

你应该返回一个包含高度元素的int []   为了达到上述目标,你应该种下你的鲜花。该   花园的前面是你回归的第一个元素   价值,是您从这里观看花园的地方。高度的元素   将是唯一的,所以总会有一个定义明确的订单。

编辑二:

示例1:

高度= {5,4,3,2,1}

盛开= {1,1,1,1,1}

萎= {365,365,365,365,365}

返回:{1,2,3,4,5}

这些花在1月1日开花,12月31日开花。由于它们都可能相互阻挡,因此您必须从最短到最高的顺序进行排序。

示例2:

H = {5,4,3,2,1}

B = {1,5,10,15,20}

W = {4,9,14,19,24}

返回:{5,4,3,2,1} 同一套花现在在不同的时间绽放。由于它们永远不会相互阻挡,因此您可以从最高到最短的顺序进行订购,以尽可能远地获得最高的。

示例3: 高度= {5,4,3,2,1}

盛开= {1,5,10,15,20}

萎= {5,10,14,20,25}

返回:{3,4,5,1,2} 这里的不同之处在于,第三种花比第四朵花开花提前一天枯萎。因此,我们可以首先放置高度为3的花,然后是高度为4的花,然后是高度为5的花,最后是高度为1和2的花。请注意,我们也可以先将它们命令为高度1,但这不是导致最大可能的高度在花园中首先出现。

11 个答案:

答案 0 :(得分:4)

这不是动态编程问题。这是一个贪婪的算法问题。

这也使我感到困惑,因为topcoder's own dynamic programming tutorial将其作为“小学”部分的练习题链接到它。

按高度对花朵进行分类,最短到最高。从一个空的行列表开始。对于每朵花(最短到最高),找到最前面的地方,你可以插入那朵花,使其不会阻挡花朵。

在Python中:

def getOrdering(height, bloom, wilt):
    flowers = zip(height, bloom, wilt)
    flowers.sort()

    def flowersOverlap(f1, f2):
        # Overlap if each blooms before the other wilts.
        return f2[1] <= f1[2] and f1[1] <= f2[2]

    rows = [ ]
    for flower in flowers:
        rowIndex = len(rows)
        # Start at the back and march forward as long as
        # `flower` wouldn't block any flowers behind it.
        while rowIndex > 0 and not flowersOverlap(flower, rows[rowIndex - 1]):
            rowIndex -= 1
        rows[rowIndex:rowIndex] = [flower]

    return [flower[0] for flower in rows]

答案 1 :(得分:2)

public int[] getOrdering(int[] height, int[] bloom, int[] wilt) {
    int[] optimal = new int[height.length];
    int[] optimalBloom = new int[bloom.length];
    int[] optimalWilt = new int[wilt.length];

    // init state
    optimal[0] = height[0];
    optimalBloom[0] = bloom[0];
    optimalWilt[0] = wilt[0];

    // run dynamic programming
    for(int i = 1; i < height.length; i ++) {
        int currHeight = height[i];
        int currBloom = bloom[i];
        int currWilt = wilt[i];

        int offset = 0; // by default, type i is to be put to 1st row
        for(int j = 0; j < i; j ++) {
            if(currWilt >= optimalBloom[j] && currWilt <= optimalWilt[j] ||
                    currBloom >= optimalBloom[j] && currBloom <= optimalWilt[j] ||
                    currWilt >= optimalWilt[j] && currBloom <= optimalBloom[j]) {  // life period overlap
                if(currHeight < optimal[j]) {  // life overlap, and type i is shorter than type j
                    offset = j;
                    break;
                } else {
                    offset = j + 1; // type i overlap with type j, and i is taller than j. Put i after j
                }
            } else {  // not overlap with current
                if(currHeight < optimal[j]) {
                    offset = j + 1; // type i not overlap with j, i is shorter than j, put i after j
                }
                // else keep offset as is considering offset is smaller than j
            }
        }

        // shift the types after offset
        for(int k = i - 1; k >= offset; k -- ) {
            optimal[k+1] = optimal[k];
            optimalBloom[k+1] = optimalBloom[k];
            optimalWilt[k+1] = optimalWilt[k];
        }
        // update optimal
        optimal[offset] = currHeight;
        optimalBloom[offset] = currBloom;
        optimalWilt[offset] = currWilt;
    }
    return optimal;
}

这是我测试过的工作代码。

答案 2 :(得分:1)

我一直在努力解决这个问题一整天,而且,我也找不到任何DP解决方案。

这是我在java中的贪婪方法,类似于已经发布的其他方法,关键点是在高度排序下进行。原因是避免处理中间高度(指已经计算过的),假设中间高度可以改变先前计算的高度的相对顺序

int[] height = new int[]{5, 3, 4};
int[] start =  new int[]{1, 3, 1};
int[] end =    new int[]{2, 4, 4};
System.out.println(Arrays.toString(new FlowerGarden().getOrdering(height, start, end)));

这是我能找到的唯一最佳子结构。但鉴于子问题之间没有重叠,这个算法不应该被视为DP而是贪婪。

private static boolean intersects(final int[] starts, final int[] ends, int i1, int i2) {
    return !(ends[i1] < starts[i2] || ends[i2] < starts[i1]);
}

public int[] getOrdering(final int[] height, final int[] starts, final int[] ends) {

    PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(new Comparator<Integer>() {
        public int compare(Integer i, Integer j) {
            return Integer.compare(height[i], height[j]);
        }
    }
    );
    for (int i = 0; i < height.length; i++) {
        minHeap.add(i);
    }
    LinkedList<Integer> list = new LinkedList<Integer>();
    while (minHeap.size() > 0) {
        Integer index = minHeap.poll();
        int p = 1;
        int pos = 0;
        for (Integer i : list) {
            if (intersects(starts, ends, i, index)) {
                pos = p;
            }
            p++;
        }
        list.add(pos, index);
    }
    int[] ret = new int[height.length];
    int j = 0;
    for (Integer i : list) {
        ret[j++] = height[i];
    }
    return ret;
}

BTW,我在这里发布的DP解决方案在这个例子中失败了。

干杯

答案 3 :(得分:0)

我也尝试解决这个问题。我的方法的主要思想是建立一个树,其中每个孩子的父母至少重叠一次。

例如,如果我们在同一天有三种花型4,2和1种生长和死亡,那么,生成的树应该是:

All nodes overlap

另一方面,如果4和2以及4和1同时存在,但是2和1不共存,那么生成的树应该是:

Two brothers

这将生成一个与问题约束一致的树。尽管如此,问题陈述还包括成本函数,使得某些解决方案比其他解决方案更好。

...你也希望将更多朝向前方的花朵尽可能高。

将此首选项投影到我们的树中的方法是从高到低排序所有“兄弟”(所有节点共享同一个父节点)。所以2首先是1。

我使用以下代码构建了这个树:

#define INT_MOD(a,b) ((a<0)?(b+(a%b)):(a%b))
#define DIST(a,b) ((a-b>=0)?(a-b):(b-a))

//Prev: ForAll(i), bloom[i] < wilt[i]
inline bool isOverlap(vector<int> & bloom,
                      vector<int> & wilt,
                      vector<int> & height,
                      unsigned int idxPrev, unsigned int idxFollowing)
{
    int f1A = bloom[idxPrev];
    int f1B = wilt[idxPrev];
    int f2A = bloom[idxFollowing];
    int f2B = wilt[idxFollowing];

    bool notIntersecting = 
    f2A > f1B /* --[--]-(--)-- */ ||
    f1A > f2B /* --(--)-[--]-- */ ;

    return height[idxPrev] > height[idxFollowing] && !notIntersecting;
}


class CPreference {
public:
    static vector<int> * pHeight;
    static bool preference(int a, int b)
    {
        return (*pHeight)[a] > (*pHeight)[b];
    }
};
vector<int> * CPreference::pHeight = NULL;

vector<int> getOrdering(vector<int> height,
                        vector<int> bloom,
                        vector<int>  wilt)
{
    int l = height.size();
    vector<int> state = vector<int>(l, -1); /*  Tree where each leave points to its
                                                parent. Being that parent the first
                                                flower type that is forced to be
                                                after (backwards) its children */

    //This loop is the dynamic programming core.
    for(int i = 0; i < l; i++)
        for(int j = INT_MOD((i-1),l); j != i; j = INT_MOD((j-1),l))
        {
            if(isOverlap(bloom, wilt, height, i, j) &&
                (state[j] < 0 || DIST(height[j],height[i]) < DIST(height[j], height[state[j]])))
            {
                state[j] = i;
            }
        }

    vector<vector<int> > groups; //Groups of indexes overlapped by the element at the same index
    for(int i = 0; i < l+1; i++)
        groups.push_back(vector<int>()); // (l+1) for no overlapped indexes group.

    for(int i = 0; i < l; i++)
    {
        int k = state[i];
  if(k < 0) k = l;
  groups[k].push_back(i);
}

CPreference::pHeight = &height;
for(vector<vector<int> >::iterator it = groups.begin(); it != groups.end(); it++)
    sort(it->begin(),it->end(), CPreference::preference);

此时,的每一行(i)包含从高到低排序的所有花类型索引,这些索引应放在索引的花类型 i

需要最后一步,将展平为输出向量。也就是说,构建一个向量,其中每个元素后跟:

  • 它的父母在树上。
  • 按高度排序的下一个兄弟。

可以通过的每个节点的深度访问来完成。我认为这是我的解决方案的弱点。我没有那么多时间所以我只是做了一个天真的递归实现:

//PRE: each vector, v, in 'groups' is sorted using CPreference
void flattenTree(vector<vector<int> > & groups, vector<int> & out, int currentIdx /*parent*/, int l)
{
    int pIdx = currentIdx;
    if(pIdx < 0) pIdx = l;

    vector<int> & elements = groups[pIdx];
    vector<int> ret;

    for(vector<int>::iterator it = elements.begin(); it != elements.end(); it++)
    {
        flattenTree(groups, out ,*it, l);
    }

    if(currentIdx>=0)
        out.push_back(currentIdx);
}

用于完成getOrdering函数:

vector<int> getOrdering(vector<int> height,
            vector<int> bloom,
            vector<int>  wilt)
{
  int l = height.size();
  vector<int> state = vector<int>(l, -1); /* Tree where each leave points to its
                         parent. Being that parent the first
                         flower type that is forced to be
                         after (backwards) its children */
  for(int i = 0; i < l; i++)
    for(int j = INT_MOD((i-1),l); j != i; j = INT_MOD((j-1),l))
      {
        if(isOverlap(bloom, wilt, height, i, j) &&
        (state[j] < 0 || DIST(height[j],height[i]) < DIST(height[j], height[state[j]])))
        {
            state[j] = i;
        }
      }

  vector<vector<int> > groups; //Groups of indexes overlapped by the element at the same index
  for(int i = 0; i < l+1; i++)
    groups.push_back(vector<int>()); // (l+1) for no overlapped indexes group.

  for(int i = 0; i < l; i++)
    {
      int k = state[i];
      if(k < 0) k = l;
      groups[k].push_back(i);
    }

  CPreference::pHeight = &height;
  for(vector<vector<int> >::iterator it = groups.begin();
      it != groups.end(); it++)
    sort(it->begin(),it->end(), CPreference::preference);

   vector<int> ret;
   flattenTree(groups, ret, -1, l);
   for(unsigned int i = 0; i < ret.size(); i++)
    ret[i] = height[ret[i]];
    return ret; 
}

如果您找到了更好的解决方案,或者知道如何改进我的解决方案,请告诉我。

答案 4 :(得分:0)

package topcoders;

import java.util.ArrayList;
import java.util.List;

public class FlowerGarden {

    public int[] getOrdering(int[] height, int[] bloom, int[] wilt) {
        int[] order = new int[height.length];
        List<Integer> heightList = new ArrayList<Integer>();
        for (int i = 0; i < height.length; i++) {
            heightList.add(height[i]);
        }
        heightList = quickSort(heightList);
        for (int i = 0; i < height.length; i++) {
            height[i] = heightList.get(i);
        }
        order = height;
        for (int i = 0; i < order.length; i++) {
            int j = 0;
            while (j < order.length - 1
                    && isBlocking(j + 1, j, order, bloom, wilt)) {
                int placeHolder = order[j];
                order[j] = order[j + 1];
                order[j + 1] = placeHolder;
                j++;
            }
        }

        return order;
    }

    public boolean isBlocking(int isBlocked, int isBlocking, int[] order,
            int[] bloom, int[] wilt) {
        if (order[isBlocking] > order[isBlocked]
                && bloom[isBlocked] <= wilt[isBlocking]
                && wilt[isBlocked] >= bloom[isBlocking]) {
            return true;
        } else {
            return false;
        }
    }

    public List<Integer> quickSort(List<Integer> array) {
        if (array.size() <= 1) {
            return array;
        }
        int pivotIndex = array.size() / 2;
        int pivot = array.get(pivotIndex);
        List<Integer> less = new ArrayList<Integer>();
        List<Integer> greater = new ArrayList<Integer>();
        int l = 0;
        int g = 0;
        for (int i = 0; i < array.size(); i++) {
            if (i == pivotIndex) {
                continue;
            } else if (array.get(i) >= pivot) {
                less.add(array.get(i));
            } else {
                greater.add(array.get(i));
            }
        }
        List<Integer> lessResult = quickSort(less);


        List<Integer> greaterResult = quickSort(greater);

        List<Integer> result = new ArrayList<Integer>();
        result.addAll(lessResult);
        result.add(pivot);
        result.addAll(greaterResult);



        return result;
    }

    public static void main(String[] args) {
        int[] height = { 5, 4, 3, 2, 1 };
        int[] bloom = { 1, 5, 10, 15, 20 };
        int[] wilt = { 5, 10, 14, 20, 25 };
        FlowerGarden g = new FlowerGarden();
        List<Integer> arrayList = new ArrayList<Integer>();
        int[] array = g.getOrdering(height, bloom, wilt);
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
    }
}

答案 5 :(得分:0)

拓扑排序方法:

#include<stdio.h>
#include<stdlib.h>
#include <vector>  
#include <queue>  

using namespace std;

#define MAX_FLOWERS 50

struct flower
{
   int id;
   int height;
   int bloom;
   int wilt;
   bool visited;
   int ind;
};

struct flower_comp
{
  bool operator()(const struct flower* lhs, const struct flower* rhs) const
  {
    return rhs->height > lhs->height;
  }   
};

inline bool overlap(const struct flower& a, const struct flower& b)
{
    return !((a.bloom < b.bloom && a.wilt < b.bloom) || (a.bloom > b.bloom && a.bloom > b.wilt));
}

void getOrdering(int height[], int bloom[], int wilt[], int size)
{
    struct flower flowers[MAX_FLOWERS];

    for(int i = 0; i < size; i++)
    {
        flowers[i].id = i;
        flowers[i].height = height[i];
        flowers[i].bloom = bloom[i];
        flowers[i].wilt = wilt[i];
        flowers[i].visited = false;
        flowers[i].ind = 0;
    } 

    bool partial_order[MAX_FLOWERS][MAX_FLOWERS] = {false};

    for(int i = 0; i < size; i++)
    {
        for(int j = i + 1; j < size; j++)
        {
            if(overlap(flowers[i], flowers[j]))
            { 
               if(flowers[i].height < flowers[j].height)
               {
                  partial_order[i][j] = true;
                  flowers[j].ind++; 
               }
               else
               {
                  partial_order[j][i] = true;
                  flowers[i].ind++; 
               }
            }
        }
    }

    priority_queue<struct flower*, vector<struct flower*>, flower_comp> pq;

    for(int i = 0; i < size; i++)
    {
        if(flowers[i].ind == 0)
        {
           pq.push(&flowers[i]);
        }
    }

    printf("{");
    bool first = true;
    while(!pq.empty())
    {
        struct flower* tmp = pq.top();
        pq.pop(); 
        tmp->visited = true;
        if(!first)
        {
           printf(",");
        }
        first = false;
        printf("%d", tmp->height);
        for(int j = 0; j < size; j++)
        {
            if(!flowers[j].visited && partial_order[tmp->id][j])
            {
               flowers[j].ind--;
               if(flowers[j].ind == 0)
               {
                  pq.push(&flowers[j]);
               }
            }
        }
    }
    printf("}\n");
}

int main(int argc, char** argv)
{
    int height[] = {5,4,3,2,1};
    int bloom[] = {1,1,1,1,1};
    int wilt[] = {365,365,365,365,365};

    getOrdering(height, bloom, wilt, sizeof(height)/sizeof(height[0]));

    int height0[] = {5,4,3,2,1};
    int bloom0[] = {1,5,10,15,20};
    int wilt0[] = {4,9,14,19,24};

    getOrdering(height0, bloom0, wilt0, sizeof(height0)/sizeof(height0[0]));

    int height1[] = {5,4,3,2,1};
    int bloom1[] = {1,5,10,15,20};
    int wilt1[] = {5,10,15,20,25};

    getOrdering(height1, bloom1, wilt1, sizeof(height1)/sizeof(height1[0]));

    int height2[] = {5,4,3,2,1};
    int bloom2[] = {1,5,10,15,20};
    int wilt2[] = {5,10,14,20,25};

    getOrdering(height2, bloom2, wilt2, sizeof(height2)/sizeof(height2[0]));

    int height3[] = {1,2,3,4,5,6};
    int bloom3[] = {1,3,1,3,1,3};
    int wilt3[] = {2,4,2,4,2,4};

    getOrdering(height3, bloom3, wilt3, sizeof(height3)/sizeof(height3[0]));

    int height4[] = {3,2,5,4};
    int bloom4[] = {1,2,11,10};
    int wilt4[] = {4,3,12,13};

    getOrdering(height4, bloom4, wilt4, sizeof(height4)/sizeof(height4[0]));

}

答案 6 :(得分:0)

与Rob相同,但在Javascript(ES6)中:

function getOrdering(height, bloom, wilt) {
    var n = height.length;

    var idx = [];
    for (var i = 0; i < n; ++i) idx[i] = i;

    idx.sort( (a, b) => height[a] - height[b] );

    var intersect = (a, b) => !(bloom[a] > wilt[b] || bloom[b] > wilt[a]);

    for (var i = 1; i < n; ++i) {
        // assume they are ordered correctly till index (i-1),
        // start moving flower i to the left until it can't move because of intersection
        var j = i, flw = idx[i];
        while (j > 0 && !intersect(idx[j-1], flw)) {
            idx[j] = idx[j-1];
            idx[--j] = flw;
        }
    }

    return idx.map( x => height[x] );
}

答案 7 :(得分:0)

类似于Rob,再次使用Python和稍微复杂的重叠bloom / wilt检查。

H = 0
B = 1
W = 2

def getOrdering(heights, blooms, wilts):

    def _f1_after_f2(f1, f2):
        fs1 = set(range(f1[B], f1[W]+1))
        fs2 = set(range(f2[B], f2[W]+1))
        return f1[H] > f2[H] if fs2.intersection(fs1) != set([]) else False

    fs = zip(heights, blooms, wilts)
    fs.sort()
    ffs = []
    for f1 in fs:
        insert_at = len(ffs)
        for f2 in reversed(ffs):
            if _f1_after_f2(f1, f2): break
            insert_at -= 1
        ffs.insert(insert_at, f1)
    return [f[H] for f in ffs]

答案 8 :(得分:0)

解决问题的图算法:

创建有向图(V,E): V - &gt;花类型 E - &gt;两种花型之间的关系

window.addEventListener("load", function() {
  var img = document.querySelector("img[src*='user_1608']");
  if (img.length) {
    img.src = "user_default.png";
  }
});

有关详细说明,请查看此论坛: Topcoder Forum - FlowerGarden

答案 9 :(得分:0)

我喜欢插入排序。对于每一朵新花,它从后到前检查,看它前面的那个是否阻挡它;如果是这样,则意味着必须放在它后面。同样,它也会从前到后进行搜索并检查后面的一个是否会阻止它;如果是这样,则意味着必须放在它前面。如果没有块,它只是检查最佳点高度。

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>

#define uint32 uint32_t

static void
Swap(int *AIdx, int *BIdx)
{
    int Tmp = *AIdx;
    *AIdx = *BIdx;
    *BIdx = Tmp;
}

static void
SwapTo(int Start, int End, int *Array)
{
    while(Start != End)
    {
        Swap(&Array[Start], &Array[Start - 1]);
        --Start;
    }
}

static void
PrintTo(int End, int *Array)
{
    for(int Idx = 0;
        Idx < End;
        ++Idx)
    {
        printf("%d, ", Array[Idx]);
    }
    printf("\n");
}

/* Does A block B? */
static bool
Blocks(int AIdx, int BIdx, int *Heights, int *Blooms, int *Wilts)
{
    bool Result = (Heights[AIdx] > Heights[BIdx] &&
                   Wilts[AIdx] >= Blooms[BIdx] && 
                   Blooms[AIdx] <= Wilts[BIdx]);

    return Result;
}

static void
Order(int *Heights, int *Blooms, int *Wilts, 
      int FlowerCount)
{
    for(int FlowerIdx = 1;
        FlowerIdx < FlowerCount;
        ++FlowerIdx)
    {
        PrintTo(FlowerIdx, Heights);

        /* front to back */
        int MinIdx = -1;
        for(int Idx = 0;
            Idx < FlowerIdx;
            ++Idx)
        {
            if(Blocks(Idx, FlowerIdx, Heights, Blooms, Wilts))
            {
                MinIdx = Idx;
                break;
            }
        }

        /* back to front */
        int MaxIdx = -1;
        for(int Idx = (FlowerIdx - 1);
            Idx >= 0;
            --Idx)
        {
            if(Blocks(FlowerIdx, Idx, Heights, Blooms, Wilts))
            {
                MaxIdx = (Idx + 1);
                break;
            }
        }

        /* best height index */
        int BestHeightIdx = -1;
        if(MinIdx == -1 &&
           MaxIdx == -1)
        {
            for(int Idx = 0;
                Idx < FlowerIdx;
                ++Idx)
            {
                if(Heights[FlowerIdx] > Heights[Idx])
                {
                    BestHeightIdx = Idx;
                    break;
                }
            }

            if(BestHeightIdx == -1)
            {
                BestHeightIdx = FlowerIdx;
            }
        }

        int SwapToIdx = -1;
        if((MaxIdx == -1 && MinIdx != -1) ||
           (MinIdx == -1 && MaxIdx != -1) ||
           (MaxIdx != -1 && MinIdx != -1 && MaxIdx == MinIdx))
        {
            SwapToIdx = (MinIdx != -1) ? MinIdx : MaxIdx;
        }
        else if(BestHeightIdx != -1)
        {
            SwapToIdx = BestHeightIdx;
        }
        else
        {
            fprintf(stderr, "Spot-finding error:\n MinIdx: %d, MaxIdx: %d, BestHIdx: %d\n",
                    MinIdx, MaxIdx, BestHeightIdx);
            exit(1);
        }

        SwapTo(FlowerIdx, SwapToIdx, Heights);
        SwapTo(FlowerIdx, SwapToIdx, Blooms);
        SwapTo(FlowerIdx, SwapToIdx, Wilts);
    }
}

int
main(int argc, char *argv[])
{
    int Heights0[]  = {5,4,3,2,1};
    int Blooms0[]   = {1,1,1,1,1};
    int Wilts0[]    = {365,365,365,365,365};

    int Heights1[]  = {5,4,3,2,1};
    int Blooms1[]   = {1,5,10,15,20};
    int Wilts1[]    = {4,9,14,19,24};

    int Heights2[]  = {5,4,3,2,1};
    int Blooms2[]   = {1,5,10,15,20};
    int Wilts2[]    = {5,10,15,20,25};

    int Heights3[]  = {5,4,3,2,1};
    int Blooms3[]   = {1,5,10,15,20};
    int Wilts3[]    = {5,10,14,20,25};

    int Heights4[]  = {1,2,3,4,5,6};
    int Blooms4[]   = {1,3,1,3,1,3};
    int Wilts4[]    = {2,4,2,4,2,4};

    int Heights5[]  = {3,2,5,4};
    int Blooms5[]   = {1,2,11,10};
    int Wilts5[]    = {4,3,12,13};

    int *AllHeights[] = {Heights0, Heights1, Heights2, Heights3, Heights4, Heights5};
    int *AllBlooms[] = {Blooms0, Blooms1, Blooms2, Blooms3, Blooms4, Blooms5};
    int *AllWilts[] = {Wilts0, Wilts1, Wilts2, Wilts3, Wilts4, Wilts5};
    int AllFlowerCounts[] = {5, 5, 5, 5, 6, 4};

    printf("\n");
    for(int Idx = 0;
        Idx < 6;
        ++Idx)
    {
        int *Heights = AllHeights[Idx];
        int *Blooms = AllBlooms[Idx];
        int *Wilts = AllWilts[Idx];
        int FlowerCount = AllFlowerCounts[Idx];

        printf("Test %d\n", Idx);
        Order(Heights, Blooms, Wilts, FlowerCount);
        printf("{ ");
        for(int Idx = 0;
            Idx < FlowerCount;
            ++Idx)
        {
            printf("%d", Heights[Idx]);
            if(Idx != (FlowerCount - 1))
            {
                printf(", ");
            }
        }
        printf(" }\n\n");
    }
}
编辑:这个解决方案太可怕了,我想出了一个更好的DP,实际上是DP;它如下:对于每朵花,环绕所有其他花朵,检查它阻挡哪些;对于它阻挡的那些花,检查它阻挡的所有花,等等,直到你得到一朵不会阻挡任何其他花的花。把那朵花放在一个新的阵列中。回溯并将每朵花放在新阵列的下一个插槽中。如果为每朵花做完,你会得到一个充满鲜花的阵列,不会阻挡任何其他花朵。然后你将每朵花尽可能向前放。这个解决方案的DP部分是,有时你会遇到已经被另一朵花阻挡的同一朵花,并且已经被放入新的阵列中,所以我们跳过那朵花而不是追逐它所阻挡的花朵。

答案 10 :(得分:0)

我已经用c ++实现了。我已经使用向量数据类型分别存储了高度,花朵和枯萎,然后将其按高度排序,然后我将花朵一一拿开,并根据与它们关联的值进行排列。

这是代码:-

#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
using namespace std;

bool comp(pair<int, pair<int,int> >& a,pair<int, pair<int,int> >& b ){
    return (a.first > b.first);
}




bool justify(pair<int, pair<int,int> >& a,pair<int, pair<int,int> >& b, int k , int 
j,  vector<pair<int,pair<int,int> > >& v){
    if(((b.second.first <= a.second.first) && (b.second.second>= a.second.first)) || 
    ((b.second.first <= a.second.second) && (b.second.second>= a.second.second)) || 
    ((b.second.first > a.second.first) && (b.second.second < a.second.second) )){

            pair<int, pair<int,int> > temp = v[j];     
          int i = j-1;
       while(i >= k){

          v[i+1] = v[i];
          i--;


        }
        v[k] = temp;
        return true;
  }
  return false;
}




int main() {

  vector<pair<int,pair<int,int> > > v;
  int n,a,b,c;
  cin>>n;
  for(int i = 0;i < n;i++){
    cin>>a>>b>>c;
    v.push_back(make_pair(a,make_pair(b,c)));
 }


sort(v.begin(), v.end(), comp);



for(int j = 1;j < n;j++){
  for(int k = 0;k < j;k++){
    bool res = justify(v[k],v[j], k, j, v);
   if(res)
   break;
  }
 }

cout<<"output"<<endl;
for(int i = 0;i < n;i++){
    cout<<v[i].first<<" "<<v[i].second.first<<" "<<v[i].second.second<<endl;
}
return 0;

}