UESTC 1271(dp動態規劃)

Description

Dreams of finding lost treasure almost came true recently. A new machine called 'The Revealer' has been invented and it has been used to detect gold which has been buried in the ground. The machine was used in a cave near the seashore where – it is said – pirates used to hide gold. The pirates would often bury gold in the cave and then fail to collect it. Armed with the new machine, a search party went into the cave hoping to find buried treasure. The leader of the party was examining the soil near the entrance to the cave when the machine showed that there was gold under the ground. Very excited, the party dug a hole two feel deep. They finally found a small gold coin which was almost worthless. The party then searched the whole cave thoroughly but did not find anything except an empty tin trunk. In spite of this, many people are confident that 'The Revealer' may reveal something of value fairly soon.

So,now you are in the point (1,1) and initially you have 0 gold.In the  n* m grid there are some traps and you will lose gold.If your gold is not enough you will be die.And there are some treasure and you will get gold.If you are in the point(x,y),you can only walk to point  (x+1,y),(x,y+1),(x+1,y+2)and (x+2,y+1).Of course you can not walk out of the grid.Tell me how many gold you can get most in the trip.

It`s guarantee that (1,1)is not a trap;

Input

first come  2 integers,  n,m( 1≤n≤1000, 1≤m≤1000)

Then follows  n lines with  m numbers    aij

   (−100<=aij<=100)

the number in the grid means the gold you will get or lose.

Output

print how many gold you can get most.

Sample Input

3 3
1 1 1
1 -5 1
1 1 1


3 3
1 -100 -100
-100 -100 -100
-100 -100 -100

Sample Output

5


1
注:剛開始用dfs結果超時。後來算了一下,每往下走一步就有4種選擇,若走了t步,共有4^t種走法,當n、m很大時,t也可能隨之增大,在加上遞歸的回溯耗時,因此會超時。

後來看了別人的題解,才明白用dp。由於還沒學dp所以在看了幾篇題解後,才理解別人的dp是怎麼用的。

注:dp數組存放的是從(1,1)到當前所在座標所蒐集的金幣的總和 。且由題意可知從(1,1)到當前座標的金幣總和爲負數時,當前點就成死點,不能繼續往下走了。

My  solution:

/*2016.3.23*/

#include<stdio.h>
#include<string.h> 
#include<algorithm>
using namespace std;
int map[1010][1010],dp[1010][1010],n,m,b[4]={1,0,1,2},d[4]={0,1,2,1};
int main()
{
	int i,j,tx,ty,k,ans;
	while(scanf("%d%d",&n,&m)==2)
	{
		ans=0;
		for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
		  scanf("%d",&map[i][j]);
			if(map[1][1]<0)//當起點爲負時,直接輸出0,不能繼續走了,因爲初始時,金幣爲0 
			;
			else
			{
				memset(dp,-1,sizeof(dp));//初始化爲-1,因爲當dp值爲0時,還可以繼續往下走。-1則表示不能繼續走的死點 
				dp[1][1]=ans=map[1][1];
				for(i=1;i<=n;i++)
				for(j=1;j<=m;j++)
				{
					if(dp[i][j]>=0)//選擇金幣總和不小於0的座標,,繼續往下走 
					{
						for(k=0;k<4;k++)
						{	
							tx=i+b[k];
							ty=j+d[k];
							if(tx>n||ty>m)
							continue ;
							//if(map[tx][ty]>=0)//不能加該條判斷,雖然當前座標自身金幣爲負,
						//	{      但從(1,1)到當前座標金幣總和卻不一定小於0,因此還有可能繼續往下走 
								dp[tx][ty]=max(dp[tx][ty],dp[i][j]+map[tx][ty]);//更新起點到當前點的座標的金幣總和 
								ans=max(ans,dp[tx][ty]);//更新最大值 
						//}
						}
					}
				}
			}
			printf("%d\n",ans);	
	}
	return 0;
}








發佈了144 篇原創文章 · 獲贊 10 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章