http://poj.org/problem?id=1042
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long LL;
#define lson num<<1, Left, Mid
#define rson num<<1|1, Mid+1, Right
#define mem(a, b) memset(a, b, sizeof(a))
/*
poj 1042 Gone Fishing
题意:有个人去湖钓鱼,有n个湖(1-n),湖的位置是线性的,
人可以从i走到i+1需要花费ti*5min,并且从1开始,任意点结束。
如果人停在一个湖钓鱼,他每钓鱼5分钟获利鱼,第一次获利fi,
下一次获利比上一次获利减di。求最大获利鱼条数。
题解:枚举结束的湖,再贪心计算在当前情况最大获利。怎么贪心?
一次一次钓,因为不用考虑路程了,取能获利最大的湖钓一次。
code:
可以用优先队列处理
*/
const int N = 30;
int d[N],t[N],f[N];
int res[N],real[N];
struct Node{
int id,val;
bool operator < (const Node &a) const {
if(val != a.val)
return val < a.val;
return id > a.id;
}
};
priority_queue<Node> Q;
int main()
{
int n,h;
bool ff = false;
while(~scanf("%d",&n) && n)
{
if(ff) puts("");
ff = true;
memset(real,0,sizeof(real));
scanf("%d",&h);
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]);
int ans,realans = -1;
for(int i = 1; i <= n; i++)
{
//init
ans = 0;
for(int j = 1; j <= n; j++)
res[j] = 0;
while(Q.size()) Q.pop();
int hh = h*12;
//begin
for(int j = 1; j < i; j++)
hh -= t[j];
for(int j = 1; j <= i; j++){
Node tmp;
tmp.id = j, tmp.val = f[j];
Q.push(tmp);
}
while(hh > 0) //注意别和我一样写成 while(hh) 因为hh可能已经为负数
{
hh --;
Node tmp = Q.top();
Q.pop();
ans += tmp.val;
res[tmp.id]+=5;
tmp.val -= d[tmp.id];
if(tmp.val < 0)
tmp.val = 0;
//他没说收益是0就不钓了,所以0还是要push进去
Q.push(tmp);
}
if(ans > realans){
realans = ans;
for(int j = 1; j <= n; j++)
real[j] = res[j];
}
}
for(int j = 1; j <= n; j++){
if(j == 1) printf("%d",real[j]);
else printf(", %d",real[j]);
}
puts("");
printf("Number of fish expected: %d\n",realans);
}
return 0;
}