题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1078
3 1 1 2 5 10 11 6 12 12 7 -1 -1
37
思路:给所以奶酪排个序,然后在找的的时候就能保证比当前节点小的奶酪已经是最优解,已经更新过了。 注意flag数组表示左上角能不能到达当前点,不能到达则不能计入更新。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 110
int m[N][N];
int flag[N][N];
int dp[N][N];
struct Node
{
int num;
int x,y;
}node[N*N];
bool cmp(Node a,Node b)
{
return a.num<b.num;
}
int main()
{
int n,k;
while(scanf("%d %d",&n,&k)&&n>0&&k>0)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
scanf("%d",&m[i][j]);
node[i*n+j].num=m[i][j];
node[i*n+j].x=i;
node[i*n+j].y=j;
}
}
sort(node,node+n*n,cmp);
memset(dp,0,sizeof(dp));
memset(flag,0,sizeof(flag));
dp[0][0]=m[0][0];
int ans=dp[0][0];
int maxn;
for(int i=0;i<n*n;i++)
{
int x=node[i].x,y=node[i].y;
maxn=-1;
for(int j=1;j<=k;j++)
{
if(x-j>=0&&m[x-j][y]<m[x][y]&&!flag[x-j][y]){
if(maxn<dp[x-j][y])
maxn=dp[x-j][y];
}
if(x+j<n&&m[x+j][y]<m[x][y]&&!flag[x+j][y]){
if(maxn<dp[x+j][y])
maxn=dp[x+j][y];
}
if(y-j>=0&&m[x][y-j]<m[x][y]&&!flag[x][y-j]){
if(maxn<dp[x][y-j])
maxn=dp[x][y-j];
}
if(y+j<n&&m[x][y+j]<m[x][y]&&!flag[x][y+j]){
if(maxn<dp[x][y+j])
maxn=dp[x][y+j];
}
}
if(maxn==-1)
{
if(x==0&&y==0)
continue;
flag[x][y]=1;
continue;
}
dp[x][y]=max(dp[x][y],maxn+m[x][y]);
ans=max(ans,dp[x][y]);
}
printf("%d\n",ans);
}
return 0;
}