题意:
给出一个n*m的图,从左上角出发,去右下角,只能向下或者向右走,每个格子有权值,问如何安排你在左上角时的权值,使得到达右下角时权值大于1。
思路:
题中给出10m时限,于是我就二分答案+dp验证咯,具体看代码。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdlib>
#include<cmath>
using namespace std;
#define MM 1000000000
int num[600][600];
int vis[600][600];
int n,m;
int low,high;
int dfs(int x)
{
vis[1][1]=x;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(i==1&&j==1)
continue;
vis[i][j]=max(vis[i-1][j],vis[i][j-1])+num[i][j];
if(vis[i][j]<=0)
vis[i][j]=-MM;
}
if(vis[n][m]>0)
return 1;
return 0;
}
void init()
{
for(int i=1;i<=n;i++)
vis[i][0]=-MM;
for(int j=1;j<=m;j++)
vis[0][j]=-MM;
low=1;
high=MM;
return ;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&num[i][j]);
init();
while(low<=high)
{
int mid=(low+high)/2;
if(dfs(mid))
high=mid-1;
else
low=mid+1;
}
int ans=high+1;
printf("%d\n",ans);
}
return 0;
}