小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

ZOJ1025-最長下降子序列

 9252娃兒 2017-01-13

ZOJ1025-Wooden Sticks 加工木棒問題

【問題描述】

現(xiàn)有n根木棒,已知它們的長度和重量。要用一部木工機(jī)一根一根地加工這些木棒。該機(jī)器在加工過程中需要一定的準(zhǔn)備時間用于清洗機(jī)器、調(diào)整工具和模板。

木工機(jī)需要的準(zhǔn)備時間如下:

(1)   第一根木棒需要1min的準(zhǔn)備時間;

(2)   在加工了一根長為l,重為w的木棒后,接著加工一根長為l’(l≤l’),

重為w’(w≤w’)的木棒是不需要任何準(zhǔn)備時間的,否則需要1min的準(zhǔn)備時間。

給定n根木棒,你要找到最少的準(zhǔn)備時間。例如現(xiàn)在有長度和重量分別為(4,9)、(5,2)、(2,1)、(3,5)和(1,4)的5根木棒,那么所需準(zhǔn)備時間最少為2min,順序為(1,4)-》(3,5)-》(4,9)-》(2,1)-》(5,2)。

【輸入】

輸入有多組測試?yán)?。輸入?shù)據(jù)的第一行是測試?yán)膫€數(shù)T。

每個測試?yán)齼尚校?/p>

第一行是一個整數(shù)n(1≤n≤5000),表示有多少根木棒;

第二行包括n×2個整數(shù),表示l1,w1,l2,w2,l3,w3,…,ln,wn,全部不大于10000,其中l(wèi)i和wi表示第i根木棒的長度和重量。

數(shù)據(jù)由一個或多個空格分隔。

【輸出】

輸出是以分鐘為單位的最少準(zhǔn)備時間,一行對應(yīng)一個測試?yán)?/p>

【輸入樣例】                                       

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


 

思路:

拿分析的樣例來看,直接想到了離散上的偏序集,但只是想到了,不知道該怎么解。。。

看了下題解有了思路。先通過一輪cmp構(gòu)造的排序,將問題進(jìn)行轉(zhuǎn)化——按照每個棒子的長度從小到大進(jìn)行排序,然后得到基于棒子長度從小到大排序的棒子重量數(shù)組,將這個數(shù)組提取到w中保存,或者你不提出來也行,我就是為了方便,我稱之為空間換簡潔。

然后我們在把2維的偏序關(guān)系降到1維后(對,這個題就是降維打擊:),就發(fā)現(xiàn)現(xiàn)在問題已經(jīng)轉(zhuǎn)換成了求w數(shù)組的最長上升子序列的最小個數(shù),而這個問題,可以再次轉(zhuǎn)換成求w數(shù)組的最長遞減子序列的長度。后者的轉(zhuǎn)換很容易理解,比如這個數(shù)組w的最長遞減子序列的長度為5,那這5個值肯定各自在一個獨(dú)立的最長上升子序列中。

兩行大概就把問題的核心說清了,然后coding


 

#include <iostream>
#include <cstring>
#include <algorithm>
#define N 5007
using namespace std;

int n,T;
struct stick{
    int l,w;
} sticks[N];
int w[N];
int dp[N];

bool cmp(stick a,stick b)
{
    if(a.l == b.l)
        return a.w < b.w;
    else if(a.l < b.l)
        return true;
    return false;
}

int LIS(int* w)
{
    int j;//j為當(dāng)前最大結(jié)束點(diǎn)的坐標(biāo) 
    dp[j=1] = w[1];
    for(int i = 2;i <= n;i++)
    {
        if(w[i] < dp[j]) 
            dp[++j] = w[i];
        else if(w[i] == dp[j]) continue;
        else {
            for(int k = j;k >= 1;k--)
            {
                if(k == 1) 
                    dp[1] = w[i]>dp[1]?w[i]:dp[1];
                //找到所有“合適”的位置 
                if(w[i]>dp[k] && w[i]<dp[k-1]) 
                    dp[k] = w[i];
            }
        }
    }
    return j;
}

int main()
{
    cin>>T;
    while(T--)
    {
        cin>>n;
        int ans = 0;
        for(int i = 1;i <= n;i++)
            cin>>sticks[i].l>>sticks[i].w;
        sort(sticks+1,sticks+1+n,cmp);
        for(int i = 1;i <= n;i++) 
            w[i] = sticks[i].w;
        cout<<LIS(w)<<endl;
    }
    return 0;
}

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多