样例输入
4 4 3 2 5 10
1 2 3 4
-1 -2 -3 -4
4 0 2 1
-4 -3 -2 -1
样例输出
10
思路
最开始是想的直接bfs暴力扩展,用优先队列存储节点,保证返回的一定是生命值最大的,并且在扩展时人为保证扩展方向,但是有几组数据没过,不知道哪里的方向没写对还是有一些小细节没注意到。
后面直接用动态规划去做,本来这道题就是动态规划问题,有三个原则:
1.如果是起点,则直接是初始值
2.如果x轴相同,那么就代表y的值发生了变化,就代表来自当前扩展方向的上一个行
3.如果y相同,那么就说明来自当前扩展方向的上一个列
4.如果x与y不同,那么就取上一行或者上一列的最大值
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[1010][1010];
int dp[1010][1010];
int main(){
int n,m,x,y,v,c;
cin >> n >> m >> x >> y >> v >> c;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> a[i][j];
}
}
int xx[4]={-1,-1,1,1};
int yy[4]={-1,1,-1,1};
for(int t=0;t<4;t++){
for(int i=x;i>0&&i<=n;i-=xx[t]){
for(int j=y;j>0&&j<=m;j-=yy[t]){
if(i==x&&j==y){
dp[i][j]=v;
}//起点
else if(i==x){//同一列,那么就是y轴变化了
dp[i][j]=min(c,dp[i][j+yy[t]]+a[i][j]);
}
else if(i==y){//同一行,x变化
dp[i][j]=min(c,dp[i+xx[t]][j]+a[i][j]);
}
else{//既不同行也不同列,那么可能就是从上一行过来,或者上一列过来
dp[i][j]=min(c,max(dp[i+xx[t]][j],dp[i][j+yy[t]])+a[i][j]);
}
if(dp[i][j]<=0){
dp[i][j]=-0x3f3f3f3f;
}
}
}
}
int ans=max(dp[1][1],max(dp[n][1],max(dp[1][m],dp[n][m])));
if(ans>0){
cout << ans << endl;
}else cout << -1 << endl;
return 0;
}
BFS未AC代码 记录一下我的自闭
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int g[1005][1005];
bool vis[4][1005][1005];
int dx[4][2]={{0,-1},{0,1},{0,-1},{0,1}};//左上,左下,右上,右下
int dy[4][2]={{-1,0},{-1,0},{1,0},{1,0}};
int n,m,x,y,v,c;
struct Node{
int x;
int y;
int blood;
Node(){};
Node(int a,int b,int c){
x=a;
y=b;
blood=c;
}
bool operator < (const Node &x)const{
return blood<x.blood;
}
};
bool check(int x,int y){
if(x<=0||y<=0||x>n||y>m)return false;
return true;
}
int bfs(int x,int y,int i){
int exey[4][2]={{1,1},{n,1},{1,m},{n,m}};
priority_queue<Node> pq;
pq.push(Node(x,y,v+g[x][y]>c?c:v+g[x][y]));
while(!pq.empty()){
Node temp=pq.top();
pq.pop();
// cout << temp.x << " " << temp.y << " " << temp.blood << endl;
if(temp.x==exey[i][0]&&temp.y==exey[i][1]){
int kkk=temp.blood+g[temp.x][temp.y];
if(kkk>c)kkk=c;
return kkk;
}
if(temp.blood<=0)continue;
for(int j=0;j<2;j++){
int ex=temp.x+dx[i][j];
int ey=temp.y+dy[i][j];
if(check(ex,ey)){
if(vis[i][ex][ey])continue;
vis[i][ex][ey]=true;
int sss=temp.blood+g[ex][ey];
if(sss>c)sss=c;
pq.push(Node(ex,ey,sss));
}
}
}
return -1;
}
int main(){
cin >> n >> m >> x >> y >> v >> c;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> g[i][j];
}
}
int ans=-1;
for(int i=0;i<4;i++){
int k=bfs(x,y,i);
//cout << k << endl;
ans=max(ans,k);
}
cout << ans << endl;
return 0;
}