标签:cnt 洛谷 int sss stick P1233 木棍 序列 include
题目:https://www.luogu.org/problemnew/show/P1233
题意:
有n根木棍,每根木棍有长度和宽度。
现在要求按某种顺序加工木棍,如果前一根木棍的长度和宽度都大于现在这根,那加工这一根就不需要准备时间,否则需要1分钟准备时间。
问最少的准备时间。
思路:
现在题目要同时维护两个单调不升序列的数目。对于一个属性显然可以通过排序保证他们是单调不升的。
只需在排好序之后求另一个属性的单调不升序列的个数。
这里需要知道Dilworth定理: 偏序集能划分成的最少的全序集的个数与最大反链的元素个数相等。
也就是说最长不升子序列的数目等于最长上升子序列的长度,最长上升子序列的数目等于最长不升子序列的长度。
问题转化成,对一个属性不升排序,再找另一个属性的最长上升子序列的长度。
用单调栈可以实现NlogN的求最长上升子序列长度,具体分析见导弹拦截。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<map> 4 #include<set> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<cmath> 9 #include<stack> 10 #include<queue> 11 #include<iostream> 12 13 #define inf 0x7fffffff 14 using namespace std; 15 typedef long long LL; 16 typedef pair<string, string> pr; 17 18 int n; 19 const int maxn = 5005; 20 struct node{ 21 int l, w; 22 }stick[maxn]; 23 int sss[maxn], cnt = 0; 24 25 bool cmp(node a, node b) 26 { 27 return a.l > b.l; 28 } 29 30 int main() 31 { 32 scanf("%d", &n); 33 for(int i = 1; i <= n; i++){ 34 scanf("%d%d", &stick[i].l, &stick[i].w); 35 } 36 37 sort(stick + 1, stick + 1 + n, cmp); 38 39 for(int i = 1; i <= n; i++){ 40 if(stick[i].w > sss[cnt - 1]){ 41 sss[cnt++] = stick[i].w; 42 //printf("%d\n", sss[cnt - 1]); 43 } 44 else{ 45 int pos = lower_bound(sss, sss + cnt, stick[i].w) - sss; 46 sss[pos] = stick[i].w; 47 } 48 } 49 printf("%d\n", cnt); 50 51 return 0; 52 }
标签:cnt,洛谷,int,sss,stick,P1233,木棍,序列,include 来源: https://www.cnblogs.com/wyboooo/p/10863859.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。