動態規劃-ZOJ 1025-WOODEN STICKS

許佳佳233發表於2016-06-24

題目:

現有n根木棒,已知它們的長度和重量。要用一部木工機一根一根地加工這些木棒。該機器在加工過程中需要一定的準備時間,是用於清洗機器,調整工具和模版的。
木工機需要的準備時間如下:
(1)第一根木棒需要1min的準備時間;
(2)在加工了一根長為l ,重為w的木棒之後,接著加工一根長為l ‘(l ≤ l’ ),重為 w’ ( w≤w’)的木棒是不需要任何準備時間的,否則需要一分鐘的準備時間。

給定n根木棒,找到最少的準備時間。例如現在有長和重分別為(4,9),(5,2),(2,1),(3,5)和(1,4)的五根木棒,那麼所需準備時間最少為2min,順序為(1,4),(3,5),(4,9),(2,1),(5,2)。

輸入

輸入有多組測試例。輸入資料的第一行是測試例的個數T。
每個測試例兩行:
第一行是一個整數n(1≤n≤5000),表示有多少根木棒;第二行包括n×2個整數,表示l1,w1,l2,w2,l3,w3,…,ln,wn,其中li和wi表示第i根木棒的長度和重量。
資料由一個或多個空格分隔。

輸出

輸出是以分鐘為單位的最少準備時間,一行一個。

輸入樣例

3
5
4 9 5 2 2 1 3 5 1 4
3
2 2 1 1 2 2
3
1 3 2 2 3 1

輸出樣例

2
1
3

分析:

1、本題關鍵之一是如何把一個二維的問題轉化成一個一維的問題。採用的方法是:先根據木棍長度把木棍進行升序排序,然後直接對重量進行處理就可以了。
2、第二個關鍵就是如何在排好序的木棍中通過重量找出能分成幾組。思路如下:
這裡寫圖片描述

程式碼:

#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;

struct node
{
    int l;
    int w;
};

int cmp(struct node x,struct node y)
{
    if(x.l==y.l)
        return x.w<y.w;
    else
        return x.l<y.l;
}


int Find(struct node t[],int n)
{
    //陣列b表示木棒分組的序號
    int b[5003];
    memset(b, 0, sizeof(b));
    b[0]=1;

    int k;
    for (int i=1; i<n; i++)
    {
        //計算第i個木棒的的分組序號
        k=0;
        for (int j=0; j<i; j++)
            if (t[i].w<t[j].w && k<b[j])
                k=b[j];    //找出儘量大的k
        b[i]=k+1;
    }

    //查詢最大的分組序號(陣列b中的最大值)
    int Max=0;
    for (int i=0; i<n; i++)
        if (b[i]>Max) Max=b[i];

    return Max;
}

int main(void)
{
    int ncase;
    struct node t[5005];

    scanf("%d",&ncase);
    while(ncase--)
    {
        int n;
        scanf("%d",&n);
        for (int i=0; i<n; i++)
            scanf("%d %d",&t[i].l,&t[i].w);

        sort(t,t+n,cmp);
        printf("%d\n",Find(t,n));
    }
    return 0;
}

相關文章