POJ1042 John釣魚 C語言代碼

POJ1042
題目不再描述了,上面是網址超鏈接。

個人遭遇···: 簡而言之,讀了N遍題。腦子裏想了半天(time>=1.5h),出現了無數想法,考慮了很多情況,仍然找不到切入點。於是,我就是CSDN找了找題解。

思路:枚舉+貪心
具體想法:
首先, 枚舉:
1 活動範圍在第1個池塘
2 活動範圍在前兩個池塘
3 活動範圍在前3個池塘
4

n 活動範圍在前n個池塘
所以,共可枚舉出n種情況。

接下來,算出每種情況的最優的釣魚總量再比較出最多的那個情況,並將這個情況中的具體操作安排好即可。
那麼,問題來了。 怎麼安排??

貪心!
先理解這個想法:
釣魚時間=總時間-路上耗費的時間;
假設John在前三個池塘活動最優方案爲:
1號池塘釣兩次,再去2號釣一次,再去3號釣2次(正常的思維順序)

代表釣一次魚
即1>1>2>3>3>
而釣魚時間=總時間-路上耗費的時間,在純粹的釣魚時間裏,
1號池塘釣兩次,2號釣一次,3號釣2次 其實次序是無所謂的
3>3>1>2>1
1>2>1>3>3
其實是和我們正常的想法在結果上是等價的。
或者說,對於一種確定的方案,先後次序是無所謂的,由於我們已經支付了路上的耗時,我們可以瞬移。
(這點需要好好想明白) (我未看題解前這點已經想到了ha ha)

貪心: 在每種情況中,不斷地在當前魚最多的池塘釣魚,直至釣魚時間爲0。

下面是我的C語言代碼:

#include<stdio.h>
#include<string.h>

//用來找到數組中最大數的下標的函數 
int find_max_i(int a[], int n){
	int i, j = 1, max = a[1];
	for( i = 2; i <= n; i++){
		if(max < a[i]) {
			max = a[i];
			j = i;
		}		//這裏是個小細節吧  題意要求:沒事幹了就在1號池塘待着 (這條註釋可以暫時忽略,需要好好想。。。) 
	}
	return j;
}

int main(){
	int n, i;//共 n 個池塘  
	int h, f[30], d[30], t[30] ={0};//共 h 小時  f數組儲存每個池塘的魚數  d數組儲存每個池塘的遞減值 t數組儲存跑路所需間隔數 
	int k;//枚舉次數 
	int fish[30], tf[30], laketime[30] [30];//fish數組儲存第K次的捕魚總數 tf數組爲f數組的copy laketime[k] [i]爲第k次 在第i個池塘釣魚的時間 
	//copy的原因:在每次枚舉中  f數組 用來提供原始數據 不能改變   而copy數組可以隨情況改變 
	int roadtime;//路上的耗時 
	int fishtime;//純粹的釣魚時間 
	
	while(scanf("%d", &n) && n ) {
		scanf("%d", &h);
		h = 60*h;//轉換爲分鐘 
		
		for(i = 1; i <= n; i++)
			scanf("%d", &f[i]);
		for(i = 1; i <= n; i++)
			scanf("%d", &d[i]);
		for(i = 1; i <= n-1; i++)
			scanf("%d", &t[i]);
			
		//對於每一次case 都要初始化 
		memset(fish, 0, sizeof(fish));
		memset(laketime, 0, sizeof(laketime));
			
		//開始枚舉 
		for(k = 1; k <= n; k++){
			roadtime = 0; 
			for(i = 1; i <= k; i++){
				tf[i] = f[i];    //copy操作 
				roadtime += 5*t[i-1]; //路上的耗時 
			}
			fishtime = h - roadtime;//純粹的釣魚時間 
			
			//貪心開始 
			while(fishtime > 0){
				i = find_max_i( tf, k);//i爲當前有最多的魚 的池塘號 
				fish[k] += tf[i];//釣魚 
				tf[i] -= d[i];//魚數遞減 
				laketime[k] [i] += 5;//在該池塘的釣魚時間
				fishtime -= 5;//總的釣魚時間減少 
				if(tf[i] < 0) tf[i] = 0;//魚釣完了 
			}
		} 
		
		//枚舉結束 開始比較 找到最優 
		k = find_max_i( fish, k);//找到 魚數 最多的那一次 
		for( i = 1; i < n; i++)//規範的打印 
			printf("%d, ", laketime[k] [i]);
		printf("%d\nNumber of fish expected: %d\n\n", laketime[k] [n], fish[k]);
	}
}

在這裏插入圖片描述
好了, 就到這裏了。
歡迎大家交流!

推薦:
https://blog.csdn.net/harrypoirot/article/details/25073835?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-6
貪心部分解釋的很好!(本文貪心部分的解釋參考了此博客)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章