Lightoj 1106 贪心

        首先我们可以枚举要走过湖泊数X,然后算出从1到X的时间。那么在这个前提下,我们可以认为fisher可以从一个湖泊“瞬间转移”到另一个湖泊,即在任意一个时刻可以从1到X中任选一个钓鱼。

        此时,走路的时间确定了,钓鱼的次数就确定了(每次5分钟),然后每次都选取f[i]最大的钓,这种贪心的思想最终能够得到一个钓鱼序列。

        你可能会跟我一样有一个疑问:因为就算是在这种情况下求出的钓鱼序列 为  1 ,5,6, 2, 3, 2,7 ,你可能会认为到了湖泊6之后再回到湖泊2可能要再花时间而且题目也不允许,但是这只是钓鱼序列,我们可以用 1 2 2 3 5 6 7 来实现这种钓鱼序列。但是总的来说求这种钓鱼序列比求实现更加容易,我用的是 o(n^2)的枚举,如果用堆的话可以进一步优化。

AC代码如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

int main(){
	int N, H;
	int f[30], d[30], t[30];
	int T, Case = 1;

	cin >> T;
	while( T-- ){

		cin >> N >> H;
		for( int i = 1; i <= N; i++ ){
			cin >> f[i];
		}
		for( int i = 1; i <= N; i++ ){
			cin >> d[i];
		}
		for( int i = 1; i < N; i++ ){
			cin >> t[i];
		}

		int fishtimes, ans_times[30], max_ans = 0;
		memset( ans_times, 0, sizeof( ans_times ) );
		for( int i = 1; i <= N; i++ ){
			
			int temp = 0;
			for( int j = 1; j < i; j++ ){
				temp += t[j] * 5;
			}
			fishtimes = ( H * 60 - temp ) / 5;

			int temp_f[30], temp_ans_times[30], temp_max_ans = 0;
			memset( temp_ans_times, 0, sizeof( temp_ans_times ) );
			for( int j = 1; j <= i; j++ )	temp_f[j] = f[j];
			for( int j = 1; j <= fishtimes; j++ ){

				int tp = 1;
				for( int k = 1; k <= i; k++ ){
					if( temp_f[k] > temp_f[tp] ){
						tp = k;
					}
				}

				temp_max_ans += temp_f[tp];
				temp_f[tp] -= d[tp];
				if( temp_f[tp] < 0 ){
					temp_f[tp] = 0;
				}
				temp_ans_times[tp] += 5;

			}

			if( temp_max_ans > max_ans ){
				for( int i = 1; i <= N; i++ ){
					ans_times[i] = temp_ans_times[i];
				}
				max_ans = temp_max_ans;
			}

		}

		cout << "Case " << Case++ << ":" << endl;
		cout << ans_times[1];
		for( int i = 2; i <= N; i++ ){
			cout << ", " << ans_times[i];
		}
		cout << endl;
		cout << "Number of fish expected: " << max_ans << endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值