我们看一下,在这个题里,所有苹果费力气也就是占背包空间不同,但是价值都是1。背包问题主要是为了解决拿得多却不一定价值最大,拿价值大的却可能装不下其他有价值的东西而使人陷入两难才被发明的算法。对于价值相同体积却不同的物品,我们每次只取体积最小的,不就能在取得当前价值的情况下,最大化剩余空间,从而拿更多苹果了吗?
讲到这里,大家可能就有点明白贪心算法的适用范围了。我之所以先引例,就是因为下面这段话实在有点晦涩难懂:
百度百科定义:贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
我语言功底有限,就不再用我贫瘠的语言来给大家详细解释这段话了。总之,这个题,用贪心确实是最优解。这点从时间复杂度上就能看出来:
搜索的基础复杂度(不加优化)是O(k^n)O(kn)(k指每个节点的选择分支的个数)的,动态规划的基础复杂度是O(nm)O(nm)(n,m分别指的是物品数量和背包大小),而贪心却只有O(n)O(n)。搜索适用范围最广,同样地时间复杂度也最高;动态规划适用范围有所缩小,但是时间复杂度也相应地提高了;贪心算法适用范围极窄,但却拥有极优的时间复杂度。万事万物都是这样,既有长处,又有短处,长短互补,向来如此。
咳咳……扯远了。下面放上贪心算法的代码。这里就不加注释了,大家借此机会锻炼一下自己的读代码能力吧。
又是一年秋季时,陶陶家的苹果树结了n个果子。陶陶又跑去摘苹果,这次她有一个a公分的椅子。当他手够不着时,他会站到椅子上再试试。
这次与NOIp2005普及组第一题不同的是:陶陶之前搬凳子,力气只剩下s了。当然,每次摘苹果时都要用一定的力气。陶陶想知道在s<0之前最多能摘到多少个苹果。
现在已知n个苹果到达地上的高度xi,椅子的高度a,陶陶手伸直的最大长度b,陶陶所剩的力气s,陶陶摘一个苹果需要的力气yi,求陶陶最多能摘到多少个苹果。
输入格式:
第1行:两个数 苹果数n,力气s。
第2行:两个数 椅子的高度a,陶陶手伸直的最大长度b。
第3行~第3+n-1行:每行两个数 苹果高度xi,摘这个苹果需要的力气yi。
输出格式:
只有一个整数,表示陶陶最多能摘到的苹果数。
输入样例#1:
8 15
20 130
120 3
150 2
110 7
180 1
50 8
200 0
140 3
120 2
输出样例#1:
4
解题代码:
#include<bits/stdc++.h>
using namespace std;
struct apple{int high;int liqi;
}aa[5001];
bool cmp(apple a,apple b){return a.liqi<b.liqi;
}
int main(){int n,s,a,b,ans=0;cin>>n>>s>>a>>b;for(int i=0;i<n;i++){scanf("%d%d",&aa[i].high,&aa[i].liqi);}sort(aa,aa+n,cmp);for(int i=0;i<n;i++){if(s<=0) break;if(aa[i].high<=(a+b) && aa[i].liqi<=s){ans++;s-=aa[i].liqi;}}cout<<ans<<endl;return 0;
}
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态