【洛谷习题】木棍加工
题目链接:https://www.luogu.org/problemnew/show/P1233
一开始的思路就是生模拟,但是感觉太奇怪了,就放弃了。
然后尝试排序,结果优先级选的是可以直接接在当前木棍后的木棍数,只对了样例。。。
看看题解,原来还可以这样玩!先只按一个属性排序,再直接找另一个属性。
具体来说,找另一个属性,就是看看最少能构成多少个最长不上升子序列,也就是其最长上升子序列的长度(根据dilworth定理)。
懒得写O(nlogn)的了,因为用的结构体,还要自己写个二分查找。
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int maxn = 5005; 7 8 struct Stick { 9 int l, w; 10 bool operator < (const Stick& rhs) const { 11 return l > rhs.l; 12 } 13 } stick[maxn]; 14 15 int dp[maxn]; 16 17 int main() { 18 int n, ans = 1; 19 scanf("%d", &n); 20 for (int i = 1; i <= n; ++i) 21 scanf("%d%d", &stick[i].l, &stick[i].w); 22 sort(stick + 1, stick + n + 1); 23 for (int i = 1; i <= n; ++i) { 24 dp[i] = 1; 25 for (int j = 1; j < i; ++j) 26 if (stick[i].w > stick[j].w) { 27 dp[i] = max(dp[i], dp[j] + 1); 28 ans = max(ans, dp[i]); 29 } 30 } 31 printf("%d", ans); 32 return 0; 33 }