poj1042 Gone Fishing(貪心)
阿新 • • 發佈:2018-12-13
思路來源
題意
有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; }