POJ 1042

利用贪心策略,以及枚举

枚举在前n个湖中选择,这样总时间h中分出固定一部分用于走遍前n个湖

这就像延迟记录的技巧,排除在前n个湖走遍的时间,之后的问题就可以转化为你可以在这n个湖中任意选择了

中间可以利用最大队优化,此处略过

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxh= 20;
const int maxn= 25+3;
const int INF= 0X7f7f7f7f;

int fi[maxn], di[maxn], ti[maxn], pln[maxn];
int ans;

inline void Init()
{
	memset(ti, 0, sizeof(ti));
	memset(pln, 0, sizeof(pln));
	ans= -INF;
}
void Copy(int bnd, int *src, int *dst)
{
	for (int i= 1; i<= bnd; ++i){
		dst[i]= src[i];
	}
}
void OutAns(const int n)
{
	for (int i= 1; i<= n; ++i){
		printf("%d", pln[i]);
		if (n!= i){
			printf(", ");
		}
	}
	putchar('
');
	printf("Number of fish expected: %d

", ans);
}
int main()
{
	int h, n, tph;
	int tpfi[maxn], tppl[maxn];
	while (EOF!= scanf("%d", &n) && n){
		scanf("%d", &h);
		Init();
		for (int i= 1; i< n+1; ++i){
			scanf("%d", fi+i);
		}
		for (int i= 1; i< n+1; ++i){
			scanf("%d", di+i);
		}
		for (int i= 1; i< n; ++i){
			scanf("%d", ti+i);
			ti[i]+= ti[i-1];
		}

		int lake;
		for (int i= 1; i< n+1; ++i){
			tph= h*60- 5*ti[i-1];
			int tpas= 0;
			Copy(i, fi, tpfi);
			memset(tppl, 0, sizeof(tppl));

			while (tph> 4){
				int maxfi= 0;

				for (int j= 1; j<= i; ++j){
					if (tpfi[j]> maxfi){
						lake= j;
						maxfi= tpfi[lake];
					}
				}

				if (maxfi<= 0){
					break;
				}

				tph-= 5;
				tppl[lake]+= 5;
				tpas+= maxfi;
				tpfi[lake]= maxfi> di[lake] ? tpfi[lake]-di[lake] : 0;
			}
			if (tpas> ans){
				ans= tpas;
				Copy(i, tppl, pln);
				pln[1]+= tph;
			}
		}
		OutAns(n);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Idi0t-N3/p/12497691.html