思路来源
https://blog.csdn.net/lyhvoyage/article/details/23289531
https://blog.csdn.net/y990041769/article/details/8522612
题意
有h小时可以钓鱼,每次钓鱼5分钟,
有n个钓鱼场所,从i到i+1场所需要5*t[i]分钟,
地点i,第一次钓鱼可以得到f[i]条鱼,
之后,每一次钓都会少d[i]条,
特别地,当f[i]-k*d[i]<=0时就钓不上来鱼了。
问最多能钓多少条鱼,输出在每个区间钓鱼的时间。
相同鱼数时,尽可能让最前面的时间多。
题解
枚举钓鱼的终止区间i,即在[0,i]这段区间钓鱼。
这里,我们将时间均换算为5分钟的倍数,h即为12*h个5min。
即刨去路上的时间,
剩下的时间可以专心钓鱼,
把这段区间的初始鱼都放进优先队列里,
优先队列里先钓大的,每钓一条鱼i,
就把它的当前权值减一次d[i]再放回去。
特别地,当权值为负时,就没法钓了。
同鱼数要求时,优先队列内部排序按pos小的先钓。
所有鱼都钓完还有时间剩余的话,全待在0号渔场。
心得
贪心题,真的好迷啊,
自己写的一个代码和答案高度相似,
也能过所有样例,
但只要不按AC代码那么改就是WA的...
代码①(WA代码)
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
const int INF=0x3f3f3f3f;
const int maxn=1e5+5;
const int mod=1e9+7;
const double eps=1e-7;
typedef long long ll;
#define vi vector<int>
#define si set<int>
#define pii pair<int,int>
#define pi acos(-1.0)
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
#define sci(x) scanf("%d",&(x))
#define scll(x) scanf("%lld",&(x))
#define sclf(x) scanf("%lf",&(x))
#define pri(x) printf("%d",(x))
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
ll n,ans,h,f[30],d[30],t[30],used[30],use[30];
struct node
{
ll v,pos;
node(ll vv,ll p):v(vv),pos(p){
};
};
bool operator<(node a,node b)
{
if(a.v==b.v)return a.pos>b.pos;
return a.v<b.v;
}
priority_queue<node>q;
void init()
{
while(!q.empty())q.pop();
mem(f,0);
mem(d,0);
mem(t,0);
mem(use,0);
mem(used,0);
ans=-1;
}
int main()
{
while(~scanf("%lld",&n)&&n)
{
init();
scll(h);h*=12;//5分钟的个数
rep(i,0,n-1)scll(f[i]);
rep(i,0,n-1)scll(d[i]);
rep(i,0,n-2)scll(t[i]);
rep(i,0,n-1)//枚举在[0,i]区间钓鱼
{
mem(use,0);
ll T=h,tmpans=0;
rep(j,0,i-1)T-=t[j];//余下的T是钓鱼时间
if(T<=0)break;//后面的没法取了
while(!q.empty())q.pop();
rep(j,0,i)q.push(node(f[j],j));
while(!q.empty()&&T)
{
node t=q.top();
ll v=t.v,pos=t.pos;
q.pop();
tmpans+=v;use[pos]++;T--;
if(v-d[pos]>0)q.push(node(v-d[pos],pos));
}
if(T)use[0]+=T;//剩下时间都呆在第一个点
if(tmpans>ans)//更新ans答案
{
ans=tmpans;
rep(j,0,n-1)used[j]=use[j];
}
else if(tmpans==ans)//更新让前面的待时间更长答案
{
bool flag=0;
rep(j,0,n-1)
{
if(use[j]>used[j])
{
flag=1;
break;
}
else if(use[j]<used[j])break;
}
if(flag)
{
rep(j,0,n-1)
used[j]=use[j];
}
}
}
printf("%lld",5*used[0]);
rep(j,1,n-1)printf(", %lld",5*used[j]);
printf("\nNumber of fish expected: %lld\n\n",ans);
}
return 0;
}
代码②(AC代码)
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
const int INF=0x3f3f3f3f;
const int maxn=1e5+5;
const int mod=1e9+7;
const double eps=1e-7;
typedef long long ll;
#define vi vector<int>
#define si set<int>
#define pii pair<int,int>
#define pi acos(-1.0)
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
#define sci(x) scanf("%d",&(x))
#define scll(x) scanf("%lld",&(x))
#define sclf(x) scanf("%lf",&(x))
#define pri(x) printf("%d",(x))
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
ll n,ans,h,f[30],d[30],t[30],used[30],use[30];
struct node
{
ll v,pos;
node(ll vv,ll p):v(vv),pos(p){
};
};
bool operator<(node a,node b)
{
if(a.v==b.v)return a.pos>b.pos;
return a.v<b.v;
}
priority_queue<node>q;
void init()
{
while(!q.empty())q.pop();
mem(f,0);
mem(d,0);
mem(t,0);
mem(used,0);
ans=-1;
}
int main()
{
while(~scanf("%lld",&n)&&n)
{
init();
scll(h);h*=12;//5分钟的个数
rep(i,0,n-1)scll(f[i]);
rep(i,0,n-1)scll(d[i]);
rep(i,0,n-2)scll(t[i]);
rep(i,0,n-1)//枚举在[0,i]区间钓鱼
{
mem(use,0);
ll T=h,tmpans=0;
rep(j,0,i-1)T-=t[j];//余下的T是钓鱼时间
if(T<=0)break;//后面的没法取了
while(!q.empty())q.pop();
rep(j,0,i)q.push(node(f[j],j));
while(T>0)
{
node t=q.top();
q.pop();
//printf("T:%d\n",T);
ll v=t.v,pos=t.pos;
if(v<=0)break;
tmpans+=v;use[pos]++;T--;
q.push(node(v-d[pos],pos));
}
if(T>0)use[0]+=T;//剩下时间都呆在第一个点
if(tmpans>ans)//更新ans答案
{
ans=tmpans;
rep(j,0,n-1)used[j]=use[j];
}
else if(tmpans==ans)//更新让前面的待时间更长答案
{
bool flag=0;
rep(j,0,n-1)
{
if(use[j]>used[j])
{
flag=1;
break;
}
else if(use[j]<used[j])break;
}
if(flag)
{
rep(j,0,n-1)
used[j]=use[j];
}
}
}
printf("%lld",5*used[0]);
rep(j,1,n-1)printf(", %lld",5*used[j]);
printf("\nNumber of fish expected: %lld\n\n",ans);
}
return 0;
}