您的位置:首页 > 其它

SSL 2331 洛谷 1717 信息学奥赛一本通 1373 鱼塘钓鱼 贪心

2018-03-09 19:34 543 查看

动态规划

温馨提示:

交洛谷请在总时间*12并调整输入格式。

题目

设计一个钓鱼方案,从第1个鱼塘出发,希望能钓到最多的鱼。

分析

首先是贪心,最后在第i个鱼塘钓鱼的话,那么路上的时间是固定的,所以也可以看成路上不需要时间,只要分别枚举钓鱼的终点鱼塘(从鱼塘1到鱼塘n)每次按照上述贪心思想确定在哪些鱼塘里钓鱼,经过n次后确定后最终得到的一定是最优方案。

贪心代码O(mn2)O(mn2)

#include <cstdio>
using namespace std;
int t[101],f[101],d[101],f1[101],la,n,m,max;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&f[i]);
for (int i=1;i<=n;i++) scanf("%d",&d[i]);
for (int i=1;i<n;i++) scanf("%d",&t[i]);
scanf("%d",&m);
for (int k=1;k<=n;k++){
int ti=m-la,ans=0,j=0;
for (int i=1;i<=k;i++) f1[i]=f[i];
for (int i=1;i<=k;i++) if (f1[i]>f1[j]) j=i;//找最大值
while (ti>0&&f1[j]>0){
if (f1[j]>0) ans+=f1[j];
f1[j]-=d[j];
for (int i=1;i<=k;i++) if (f1[i]>f1[j]) j=i;//更新
ti--;
}
max=(max>ans)?max:ans;
la+=t[k];
}
printf("%d",max);
return 0;
}


贪心+大根堆(用大根堆优化时间O(mnlog2n)O(mnlog2n)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct heap{
int fish,lake;
}w[101];
int t[101],f[101],d[101],n,m,la,maxx;
void down(int x){//下移操作
int y;
while ((x<<1)<=n){
if ((x<<1)==n||w[(x<<1)].fish>w[(x<<1)+1].fish) y=x*2; else y=x*2+1;
if (w[x].fish<w[y].fish) swap(w[x],w[y]); x=y;
}
}
void up(int x){while //上移操作
(x>1&&w[x>>1].fish>w[x].fish) swap(w[x],w[x>>1]),x>>=1;}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&f[i]);
for (int i=1;i<=n;i++) scanf("%d",&d[i]);
for (int i=1;i<n;i++) scanf("%d",&t[i]);
scanf("%d",&m);
for (int k=1;k<=n;k++){
int ti=m-la,ans=0;
for (int i=1;i<=k;i++) w[i].fish=f[i],w[i].lake=i;
for (int i=1;i<=k/2;i++) down(i);//维护大根堆
while (ti>0&&w[1].fish>0){
ans+=w[1].fish;
w[1].fish-=d[w[1].lake];
down(1); ti--;
}
if (ans>maxx) maxx=ans; la+=t[k];
}
printf("%d",maxx);
return 0;
}


贪心+STL优先队列代码(和上一个时间差不多)

#include <cstdio>
#include <queue>
using namespace std;
priority_queue <pair<int,int> >heap;
int t[101],f[101],d[101],n,m,la,maxx;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&f[i]);
for (int i=1;i<=n;i++) scanf("%d",&d[i]);
for (int i=1;i<n;i++) scanf("%d",&t[i]);
scanf("%d",&m);
for (int k=1;k<=n;k++){
int ti=m-la,ans=0;
for (int i=1;i<=k;i++) heap.push(make_pair(f[i],i));
while (ti>0&&heap.top().first>0){
pair<int,int>g=heap.top();
heap.pop();//弹出
ans+=g.first;
g.first-=d[g.second];//修改
heap.push(g);//插入
ti--;
}
if (ans>maxx) maxx=ans;
la+=t[k];
}
printf("%d",maxx);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: