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
後來看了別人的題解,才明白用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;
}