总结报告—第三周—贪心总结
这一周,我去听了贪心算法的例题课,感觉贪心的有些题确实是不好想,不好把握。在前几周里我拿出了一点时间看了看贪心的视频,大体了解了什么是贪心,贪心算法的经典处理方法,感觉自己欠缺的太多,需要补的内容不少。
贪心例题总结
换食物问题(性价比)
-
问题阐述
一个人可以到n个房间用自己持有的猫粮换取自己的食物,他总共有M磅猫粮,房间的食物可按比例交换,求解他可以换取的最多食物。 -
求解思路
找换取性价比最高的房间去换,直到自己手中无猫粮。
先排序找性价比最高的房间,再依次换取食物,直到没猫粮结束。 -
代码展示
#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
struct pp{
double p, d;
}a[10005];
int cmp( pp k, pp s){
return k. p/k. d>s. p/s. d;
}
int main(){
double M;
int N;
while(cin>>M>>N&&(M!=-1||N!=-1)){
memset(a,0,sizeof(a));
for(int i=1;i<=N;i++){
cin>>a[i]. p>>a[i]. d;
}
sort(a+1, a+1+N,cmp);
//for(int i=1;i<=N;i++){
//cout<<a[i].p<<" "<<a[i].d<<endl;
//}
double sum=0;
for(int i=1;i<=N;i++){
if(M-a[i]. d>=0){
sum+=a[i]. p;
M=M-a[i]. d;
}
else{
sum+=a[i].p*(M/a[i].d);
break;
}
}
cout <<fixed<< setprecision(3) << sum<<endl;
}
}
细节
1.结构体要熟练使用,结构体数组的排序很方便,否则代码长且超时容易出错。
2.输出格式问题:要加强scanf、printf的使用,我用的并不熟练,而且cout输出保留小数点后三位也要会用。
铺桥问题(过泥潭)
-
问题阐述
在数轴上在两点之间存在泥潭,要用长度为L的木板铺桥,木板可重叠,求铺桥用的最少木板数。 -
思路
从数轴的一段出发,到另一端,要求如果木板长度多出来尽可能向数轴的另一端倾斜,如果前面铺上了木板,则无需再铺,只需计算没铺的位置即可。 -
代码
#include<iostream>
#include<algorithm>
using namespace std;
struct pp{
int p, d;
}a[10005];
int cmp( pp k, pp s){
return k.p<s.p;}
int main(){
int n, l;
cin>>n>>l;
int h=0;
for(int i=1;i<=n;i++){
cin>>a[i]. p>>a[i]. d;
}
sort(a+1, a+1+n,cmp);
int last=a[1].d;
int x=0;
x=last-a[1].p;
if(x%l==0)
h=h+x/l;
else{
h=h+x/l+1;
last=a[1].p+(x/l+1)*l;
}
for(int i=2;i<=n;i++){
if(last>=a[i]. d)
continue;
else if(last>a[i]. p){
x=a[i].d-last;
if(x%l==0){
h=h+x/l;
last=a[i]. d;
}
else{
h=h+x/l+1;
last=last+((x/l)+1)*l;
}
}
else{
last=a[i].d;
x=last-a[i].p;
if(x%l==0){
h=h+x/l;
last=a[i]. d;
}
else{
h=h+x/l+1;
last=a[i].p+((x/l)+1)*l;
}
}
}
cout<<h<<endl;
}
细节
位置切换,每铺上木板,都要计算一下末位置,再从末位置出发,铺木板。
int last=a[1].d;
int x=0;
x=last-a[1].p;
if(x%l==0)
h=h+x/l;
else{
h=h+x/l+1;
last=a[1].p+(x/l+1)*l;
}
for(int i=2;i<=n;i++){
if(last>=a[i]. d)
continue;
else if(last>a[i]. p){
x=a[i].d-last;
if(x%l==0){
h=h+x/l;
last=a[i]. d;
}
else{
h=h+x/l+1;
last=last+((x/l)+1)*l;
}
}
else{
last=a[i].d;
x=last-a[i].p;
if(x%l==0){
h=h+x/l;
last=a[i]. d;
}
else{
h=h+x/l+1;
last=a[i].p+((x/l)+1)*l;
}
}
}
贪心经典例题思考
1.作业调度问题
权衡作业的价值,先找扣分多的,在规定日期内尽量往后排,在把前面的空位按扣分从多到少补上,最后没有空位置的话就舍弃,将扣分加和得到答案。
2.活动安排问题
将活动按结束时间从早到晚排序,从早到晚筛选,如果与前一个活动不冲突,自动选中。(使剩余时间尽可能多,从而做更多活动)
3.节约成本问题
合理调配空间租金和生产成本,使它最小,列数学等式解决。
感受
这段时间,课下刷题少,平时用的时间并不是很多,贪心掌握的一般。对于贪心问题,就是从局部最优到整体最优的求解,有些问题确实并不好想。有些需要找规律,有些规律较明显但是代码复杂,需要优化等等,好多问题都需要静下心来解决,慢慢找规律。
我的问题出现在思路过于狭窄或繁琐导致代码写不出来,或者没思路。问题主要在于思路,要学会往可以写出最简代码的方向想,多锻炼一下思路,多刷题。平常也多学学写代码,优化代码使其更加简练易懂。
下一步要努力跟上进度,平常提高效率,多花时间来刷题总结,希望自己可以尽快赶上,跟上进度,做得更好!