【oiClass 2085】马(排序,DP)

题目描述

战神阿瑞斯听说2008年在中华大地上,将举行一届规模盛大的奥林匹克运动会,心中顿觉异常兴奋,他召集了n位天将,骑着他们自己的天马,准备在广阔的天空上,举行一场空前的天马天将列队表演。天马在熟悉了自己的天将以后,已经是将马合一,不能分开了。战神阿瑞斯想在这n匹天马和n个天将中选出尽可能多的天马和天将,组成一个队列,该队列必须同时满足:
(1)队列中天将的高度加上天马的高度之和,后一个应该比前一个大。
(2)队列中后一个天马高度不低于前一个天马高度,队列中后一个天将高度不低于前一个天将高度。
应该怎样选才能使队列的长度最大呢?你能给战神阿瑞斯参谋参谋吗? 

输入

输入文件horse.in 的第一行只有一个正整数n,表示共有n匹马和n个天将。
第二行共有n个正实数,分别表示每匹天马的高度,第i个数表示第i匹天马的高度。这n个数之间互相以一个空格分隔。
第三行共有n个正实数,分别表示每个天将的身高,第i个数表示第i个天将的高度。这n个数之间互相以一个空格分隔。

输出

输出文件horse.out中只有一行,该行只有一个正整数,为符合条件的最长队列长度。
按照马的高度排序,若发现相邻两人马与将身高都一致,则“删除”此节点,然后再排一次。由于此时马的高度已经排好,我们只需要求出以将军高度决定的最长不下降子序列即可。
 1 #include <algorithm>
 2 #include <cstdio>
 3  
 4 struct fighters{
 5     float h,f;
 6 }a[9001];
 7  
 8 int n,ans,tot=1;
 9 float maxn,f[9001];
10 #define max(x,y) (x>y?x:y)
11  
12 bool cmp(fighters x,fighters y){
13     if(x.h==y.h)return x.f<y.f;
14     return x.h<y.h;
15 }
16  
17 int main(void){
18     scanf("%d",&n);
19     for(int i=1;i<=n;++i)
20         scanf("%f",&a[i].h);
21     for(int i=1;i<=n;++i)
22         scanf("%f",&a[i].f);
23     std::sort(a+1,a+n+1,cmp);
24     for(int i=1;i<n;++i)
25         if((a[i].f==a[i+1].f)&&(a[i].h==a[i+1].h))
26             a[i].f=10;
27     std::sort(a+1,a+n+1,cmp);
28     f[1]=a[1].f;
29     for(int i=2;i<=n;++i){
30         if(a[i].f>=f[tot]){
31             f[++tot]=a[i].f;
32             continue;
33         }
34         int j=std::upper_bound(f+1,f+tot+1,a[i].f)-f;
35         f[j]=a[i].f;
36     }
37     printf("%d",tot);
38 }

 

转载于:https://www.cnblogs.com/gzh01/p/9374712.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值