http://poj.org/problem?id=1065
题意: 锯木机 开机首先要了1分钟 之后据木头 如果木头的长宽均小于等于上一块 就不需要重启 不然重启又花费一分钟
问最短 花费时间
思路:看了题解才明白可以转LIS 最长上升子序列
首先 按照长度 由大到小排序 相同时 按照宽度由大到小排序
鸽笼原理 形成LIS长度的 递减序列 // 难以想象
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <list>
using namespace std;
typedef long long ll;
const int maxn =5000+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI=acos(-1.0);
struct node{
int h,w;
bool operator<(const node &a) const {return (h==a.h&&w>a.w)||h>a.h;}
}sticks[maxn];
int dp[maxn],a[maxn];
int main(){
int t,n;
cin>>t;
while(t--){
memset(dp,INF,sizeof(dp));
cin>>n;
for(int i=0;i<n;i++) cin>>sticks[i].h>>sticks[i].w;
sort(sticks,sticks+n);
for(int i=0;i<n;i++) a[i]=sticks[i].w;
for(int i=0;i<n;i++)
*lower_bound(dp,dp+n,a[i])=a[i];
// for(int i=0;i<n;i++) cout<<a[i]<<" ";cout<<endl;
printf("%d\n",lower_bound(dp,dp+n,INF)-dp);
}
return 0;
}