(算法)Game

题目:

Jeff loves playing games, Gluttonous snake( an old game in NOKIA era ) is one of his favourites. However, after playing gluttonous snake so many times, he finally got bored with the original rules.In order to bring new challenge to this old game, Jeff introduced new rules :
1.The ground is a grid, with n rows and m columns(1 <= n, m <= 500).

2.Each cell contains a value v (-1<=vi<=99999), if v is -1, then this cell is blocked, and the snakecan not go through, otherwise, after the snake visited this cell, you can get v point.

3.The snake can start from any cell along the left border of this ground and travel until it finally stops at one cell in the right border.

4.During this trip, the snake can only go up/down/right, and can visit each cell only once.Special cases :
  a. Even in the left border and right border, the snake can go up and down. 
  b. When the snake is at the top cell of one column, it can still go up, which demands the player to  pay  all current points , then the snake will be teleported to the bottom cell of this column and vice  versa.

After creating such a new game, Jeff is confused how to get the highest score. Please help him to write a program to solve this problem.
Input
  The first line contains two integers n (rows) andm (columns), (1 <= n, m <= 500), separated by a      single space.
  Next n lines describe the grid. Each line contains m integers vi (-1<=vi<=99999) vi = -1 means the cell is blocked.
Output
  Output the highest score you can get. If the snake can not reach the right side, output -1.Limits

Sample Test
Input
4 4

-1 4 5 1

2 -1 2 4

3 3 -1 3

4 2 1 2
output
23
Path is as shown below

 

Input
4 4

-1 4 5 1

2 -1 2 4

3 3 -1 -1

4 2 1 2
output
16

Path is as shown below

思路:

1、回溯法

2、动态规划

代码:

1、回溯法

#include<iostream>
#include<vector>

using namespace std;

int cx[]={-1,0,1};
int cy[]={0,1,0};

void dfs(const vector<vector<int> > &grid,long long sum,int x,int y,vector<vector<bool> > &visited,long long &ans){
    int m=grid.size();
    int n=grid[0].size();

    if(y==n-1 && sum>ans)
        ans=sum;

    for(int i=0;i<3;i++){
        bool flag=false;
        int nx=x+cx[i];
        if(nx==-1){
            nx=m-1;
            flag=true;
        }
        if(nx==m){
            nx=0;
            flag=true;
        }
        int ny=y+cy[i];
        if(ny==n)
            continue;
        if(visited[nx][ny] || grid[nx][ny]==-1)
            continue;
        visited[nx][ny]=true;
        if(flag)
            dfs(grid,grid[nx][ny],nx,ny,visited,ans);
        else
            dfs(grid,sum+grid[nx][ny],nx,ny,visited,ans);
        visited[nx][ny]=false;
    }
}


int main(){
    int val;
    int row_num,col_num;
    while(cin>>row_num>>col_num){
        if(row_num>0 && col_num>0){
            vector<vector<int> > grid(row_num,vector<int>(col_num));
            vector<vector<bool> > visited(row_num,vector<bool>(col_num,false));
            for(int i=0;i<row_num;i++){
                for(int j=0;j<col_num;j++){
                    cin>>val;
                    if(val>=-1)
                        grid[i][j]=val;
                    else
                        return 0;
                }
            }
            
            long long highestScore=0;
            long long sum=0;

            for(int i=0;i<row_num;i++){
                if(grid[i][0]==-1)
                    continue;
                visited[i][0]=true;
                dfs(grid,grid[i][0],i,0,visited,highestScore);
                visited[i][0]=false;
            }
            cout<<highestScore<<endl;
        }
    }
    return 0;
}

2、动态规划

#include<iostream>
#include<vector>
#include<stdlib.h>

using namespace std;

//int row_num,col_num;

long long getScore(const vector<vector<int> > &grid,vector<vector<long long> > &scores);

int main(){
    int val;
    int row_num,col_num;
    while(cin>>row_num>>col_num){
        if(row_num>0 && col_num>0){
            vector<vector<int> > grid(row_num,vector<int>(col_num));
            for(int i=0;i<row_num;i++){
                for(int j=0;j<col_num;j++){
                    cin>>val;
                    if(val>=-1)
                        grid[i][j]=val;
                    else
                        return 0;
                }
            }
            
            long long highestScore=0;
            vector<vector<long long> > scores(row_num,vector<long long>(col_num+1,0));

            highestScore=getScore(grid,scores);

            if(highestScore!=0)
                cout<<highestScore<<endl;
            else
                cout<<-1<<endl;
            }
        }
        return 0;
    }
        
long long getScore(const vector<vector<int> > &grid,vector<vector<long long> > &scores){
    int row_num=grid.size();
    int col_num=grid[0].size();
    long long tmp;
    int last;
    long long highestScore=0;

    for(int j=0;j<col_num;j++){
        for(int i=0;i<row_num;i++){
            if(grid[i][j]==-1){
                scores[i][j+1]=-1;
                continue;
            }

            if(scores[i][j]==-1)
                continue;
                        
            // move down
            last=i;
            tmp=scores[i][j]+grid[i][j];
            scores[i][j+1]=max(tmp,scores[i][j+1]);

            for(int k=i+1;;k++){
                k=(k+row_num)%row_num;
                if(grid[k][j]==-1 || k==i)
                    break;
                else{
                    // transported
                    if(abs(k-last)>1){
                        scores[k][j+1]=scores[k][j+1]>grid[k][j]?scores[k][j+1]:grid[k][j];
                        tmp=grid[k][j];
                    }
                    else{
                        tmp+=grid[k][j];
                        if(tmp>scores[k][j+1])
                            scores[k][j+1]=tmp;
                        }
                    last=k;
                }
            }

            //move up
            last=i;
            tmp=scores[i][j]+grid[i][j];
            scores[i][j+1]=max(tmp,scores[i][j+1]);

            for(int k=i-1;;k--){
                k=(k+row_num)%row_num;
                if(grid[k][j]==-1 || k==i)
                    break;
                else{
                    if(abs(k-last)>1){
                        scores[k][j+1]=scores[k][j+1]>grid[k][j]?scores[k][j+1]:grid[k][j];
                        tmp=grid[k][j];
                    }
                    else{
                        tmp+=grid[k][j];
                        if(tmp>scores[k][j+1])
                            scores[k][j+1]=tmp;
                    }
                }
                last=k;
            }
        }    
    }
    
    for(int i=0;i<row_num;i++)
        highestScore=max(highestScore,scores[i][col_num]);
    

    return highestScore;
}

 

转载于:https://www.cnblogs.com/AndyJee/p/4887055.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值