HDU-1051 一个DP问题

Problem Description

There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a woodworking machine in one by one fashion. It needs some time, called setup time, for the machine to prepare processing a stick. The setup times are associated with cleaning operations and changing tools and shapes in the machine. The setup times of the woodworking machine are given as follows:

(a) The setup time for the first wooden stick is 1 minute.
(b) Right after processing a stick of length l and weight w , the machine will need no setup time for a stick of length l' and weight w' if l<=l' and w<=w'. Otherwise, it will need 1 minute for setup.

You are to find the minimum setup time to process a given pile of n wooden sticks. For example, if you have five sticks whose pairs of length and weight are (4,9), (5,2), (2,1), (3,5), and (1,4), then the minimum setup time should be 2 minutes since there is a sequence of pairs (1,4), (3,5), (4,9), (2,1), (5,2).

Input

The input consists of T test cases. The number of test cases (T) is given in the first line of the input file. Each test case consists of two lines: The first line has an integer n , 1<=n<=5000, that represents the number of wooden sticks in the test case, and the second line contains n 2 positive integers l1, w1, l2, w2, ..., ln, wn, each of magnitude at most 10000 , where li and wi are the length and weight of the i th wooden stick, respectively. The 2n integers are delimited by one or more spaces.

Output

The output should contain the minimum setup time in minutes, one per line.

分析

  这道题是问将一组木条划分一下,要求每个链中长度和重量是不下降的,求最少能分出几个链,好像挺眼熟的感觉?没错这不是导弹拦截吗?如果你对迪尔沃斯(音译)定理了解足够深的话,接下来怎么做就很明了了,最少链的划分=最长反链的长度,数据n<=5000,n2就可以不需要加优化。

  如果你很好奇定理证明,自行百度……

  

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=1e5+10;
 6 int dp[N];
 7 struct Node{
 8     int l,w;
 9     bool operator <(const Node &A)const{
10         if(l==A.l){
11             if(w==A.w)return 1;
12             return w<A.w;
13         }
14         return l<A.l;
15     }
16 }a[N];
17 int main(){
18     int t;
19     cin>>t;
20     while(t--){
21         int n;
22         memset(dp,0,sizeof(dp));
23         cin>>n;
24         for(int i=1;i<=n;i++){
25             cin>>a[i].l>>a[i].w;
26         }
27         sort(a+1,a+n+1);
28         int ans=0;
29         for(int i=1;i<=n;i++){
30             dp[i]=1;
31             for(int j=1;j<i;j++)
32                 if(a[j].w>a[i].w)
33                     dp[i]=max(dp[j]+1,dp[i]);
34             ans=max(dp[i],ans);
35         }
36         cout<<ans<<endl;
37     }
38 }

 

posted @ 2020-04-01 11:03  An_Fly  阅读(88)  评论(0编辑  收藏  举报