1. 程式人生 > >NYOJ 625 笨蛋的難題(二)

NYOJ 625 笨蛋的難題(二)

剛開始以為是博弈方面的問題,浪費了不少時間。

這道題的解法有點像動態規劃,同時也有點貪心的意思

總體思想是倒推,分解成多個子問題,從後往前算...first記錄從當前位置向後先取的最大值,last記錄從當前位置向後取的最大值..v[i]為當前處理的工資..

核心部分如下:

		first=0;
		last=0;
		for(i=t-1;i>=0;i--)	
			if(v[i]+last>=first)		//如果成立,則取v[i],否則不取
			{
				tem=last;
				last=first;
				first=v[i]+tem;
			}

因為總是要自己取得最大值,所以,在判斷是不是取v[i]時,只需判斷是取v[i]能獲得的錢多,還是放棄v[i],取v[i+1]獲得的錢多(有可能v[i+1]也放棄);

如果要取v[i]的話,必定有v[i]+last>=first成立(等號不能去),在這裡,last,first均是上一個子問題的結果,即從i+1開始,先取能獲得的最大值,後取能獲得的最大值。所以,v[i]+last即為當前子問題中的先取獲得的最大值,first為當前子問題中後取能獲得的最大值(放棄v[i])。

然後,將first賦值為v[i]+last(上一個子問題中的last), last賦值為上一個子問題中的first。

#include <stdio.h>

int main()
{
	int v[125];
	int t;
	int tem;
	int sum;
	int i;
	int first,last;
	while(scanf("%d",&t)!=EOF)
	{
		sum=0;
		for (i=0;i<t;i++)
		{
			scanf("%d",&v[i]);
			sum+=v[i];
		}
		first=0;
		last=0;
		for(i=t-1;i>=0;i--)	
			if(v[i]+last>=first)		//如果成立,則取v[i],否則不取
			{
				tem=last;
				last=first;
				first=v[i]+tem;
			}


			printf("%d %d %d\n",first,last,sum-first-last);
	}
	return 0;
}