您的位置:首页 > 其它

【DBSDFZOJ 4430】陶陶摘苹果(DP)

2017-09-27 08:32 295 查看

Description

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出 n 个苹果。苹果成熟的时候,陶

陶就会跑去摘苹果。

陶陶的手不能弯 (他仅能把手伸直),当且仅当陶陶达到的高度与苹果的高度相等的时

候,陶陶才能摘到苹果。

好在陶陶有 m 个板凳,每个板凳的高度可以在区间 [li, ri] 之间上下移动 (即可以随时 变为该区间中任何一个值)。当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。

但是搬板凳对陶陶来说是一件费力的事情,所以他只能选择 k 个板凳来使用。

现在已知 n 个苹果到地面的高度,m 个板凳的高度区间,陶陶能选择的板凳数 k,以

及陶陶把手伸直能达到的高度 h,请帮陶陶算一下她最多能够摘到的苹果的数目。假设她碰

到苹果,苹果就会掉下来。

Input

第一行四个正整数 n,m,h,k,表示苹果的数量、板凳的数量、陶陶把手伸直能达到

的高度和陶陶最多选择的板凳数量。

第一行包含 n 个正整数,第 i 个正整数 ai 表示第 i 个苹果到地面的高度,两个相邻的

整数之间用一个空格隔开。

接下来 m 行,每行两个非负整数 li,ri,表示第 i 个板凳的高度区间。

Output

一个数,表示最多摘到的苹果数。

Sample Input

10 5 110 3

100 200 150 140 129 134 167 198 200 111

0 30

20 40

90 100

100 110

50 60

Sample Output

7

Data Constraint

对于 30% 的数据,m≤10,ai, h≤1000,li

解题思路

dp,先将板凳按右端点排序,用f[i][j]表示一共选了i个板凳,最后一个板凳编号为j。所以可以枚举上一个板凳的位置,转移方程为f[i][j]=max{ f[i-1][i-1]~f[i-1][j-1] }。

代码

#include <bits/stdc++.h>
using namespace std;
int n,m,h,k;
int tree[1000005];
int f[205][205];
struct qj{
int l,r;
}d[205];
bool cmp(qj a,qj b){return a.r<b.r;}
int main(){
scanf("%d%d%d%d",&n,&m,&h,&k);
int Max=-1;
for(int i=1;i<=n;++i){
int a;
scanf("%d",&a);a-=h;
if(a<0) continue;
Max=max(Max,a);
tree[a]+=1;
}
for(int j=1;j<=m;++j){
scanf("%d%d",&d[j].l,&d[j].r);
Max=max(Max,d[j].r);
}
for(int i=1;i<=Max;++i)     tree[i]+=tree[i-1];
sort(d+1,d+m+1,cmp);
int ans=0;
for(int i=1;i<=k;++i)
for(int j=1;j<=m;++j)
for(int p=i-1;p<j;++p){
f[i][j]=max(f[i][j],f[i-1][p]+tree[d[j].r]-max((d[j].l?tree[d[j].l-1]:0),tree[d[p].r]));
ans=max(ans,f[i][j]);
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: