洛谷 P1233 木棍加工(LIS,狄尔沃斯定理)
传送门
解题思路
先按照l为第一关键字,w为第二关键字从大到小排序,保证前面的l一定比后面的大于等于,这样就能排除一维影响。
然后问题就变成了在排好序的序列中找最长不上升子序列的个数,根据狄尔沃斯定理(导弹拦截定理),我们得知最长不上升子序列的个数就等于最长上升子序列的长度。
所以这里O(n^2)求即可。
注意n^2算法的答案不是dp[n],而是计算dp时ans取max。
AC代码
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstdio> 5 #include<cstring> 6 using namespace std; 7 const int maxn=5005; 8 struct node{ 9 int l,w; 10 }a[maxn]; 11 int n,dp[maxn],ans; 12 bool cmp(node a,node b){ 13 return a.l!=b.l?a.l>b.l:a.w>b.w; 14 } 15 int main() 16 { 17 cin>>n; 18 for(int i=1;i<=n;i++) cin>>a[i].l>>a[i].w; 19 sort(a+1,a+n+1,cmp); 20 for(int i=1;i<=n;i++){ 21 dp[i]=1; 22 for(int j=1;j<i;j++){ 23 if(a[i].w>a[j].w) dp[i]=max(dp[i],dp[j]+1); 24 } 25 ans=max(ans,dp[i]); 26 } 27 cout<<ans; 28 return 0; 29 }