两种方法。。。
方法一720ms,方法二612ms。
======================================================================================================
方法一: 二分枚举 + 简单DP
比赛结束之后,听到他们都用这个方法,就自己写了一下~~
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define f(x) ((x)>0?(x):-50000000)
using namespace std;
int s[510][510];
int dp[510][510];
int n,m;
int deal(int source){
int i,j,tmp;
dp[1][1]=source;
for(j=2;j<=m;j++)
dp[1][j]=f(dp[1][j-1]+s[1][j]);
for(i=2;i<=n;i++){
dp[i][1]=f(dp[i-1][1]+s[i][1]);
for(j=2;j<=m;j++)
dp[i][j]=f(max(dp[i-1][j],dp[i][j-1])+s[i][j]);
}
return dp[n][m];
}
int main(){
int t,i,j,l,r,mid,tmp;
for(scanf("%d",&t);t--;){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&s[i][j]);
l=1,r=10000000;
while(l<=r){
mid=(l+r)>>1;
if(deal(mid)>0) r=mid-1;
else l=mid+1;
}
printf("%d\n",l);
}
return 0;
}
===============================================================================================
方法二: 优先队列 + 二维搜索
比赛中一直WA,不明原因,一直觉得思路没错。。。
在使用方法一将这题A了之后,又不信邪地再把这个代码翻出来。。。
随机数据对照了一下,发现原因竟然是,忘记在下一组测试数据之前初始化优先队列。。。
囧。。。添上就AC了。。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int n,m;
int mp[600][600],sum[600][600],mx[600][600];
struct Point{
int x,y,mx,sum;
Point(){}
Point(int a,int b,int c,int d){x=a,y=b,sum=c,mx=d;}
bool friend operator<(Point a,Point b){
if(a.mx!=b.mx) return a.mx<b.mx;
return a.sum<b.sum;
}
};
priority_queue<Point>que;
int fx[]={1,0};
int fy[]={0,1};
int bfs(){
int k,i,j;
Point now,next;
for(i=0;i<n;i++)
for(j=0;j<m;j++) mx[i][j]=sum[i][j]=-30000000;
while(!que.empty())que.pop();
que.push(Point(0,0,0,0));
mx[0][0]=sum[0][0]=0;
while(!que.empty()){
now=que.top();
que.pop();
if(now.x==n-1 && now.y==m-1) return now.mx;
for(k=0;k<2;k++){
next.x=now.x+fx[k];
next.y=now.y+fy[k];
if(next.x>=n || next.y>=m) continue;
next.sum=now.sum+mp[next.x][next.y];
next.mx=min(next.sum,now.mx);
if(next.sum>sum[next.x][next.y] || next.mx>mx[next.x][next.y]){
que.push(next);
if(next.sum>sum[next.x][next.y])
sum[next.x][next.y]=next.sum;
if(next.mx>mx[next.x][next.y])
mx[next.x][next.y]=next.mx;
}
}
}
return 0;
}
int main(){
int res,t,i,j;
for(scanf("%d",&t);t--;){
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&mp[i][j]);
res=bfs();
printf("%d\n",res>=0?1:-res+1);
}
}