poj1042 Gone Fishing(贪心)

思路来源

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。

即刨去路上的时间,

剩下的时间12*h-\sum t[j],0<=j<i可以专心钓鱼,

把这段区间的初始鱼都放进优先队列里,

优先队列里先钓大的,每钓一条鱼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;	
}

猜你喜欢

转载自blog.csdn.net/Code92007/article/details/82930584
今日推荐