UVa:10913 Walking on a Grid

上个月刷动规被这个题给卡到,主要是纠结在还可以往左走这个地方上。

今天回切动规,终于想到了办法。

晚上再写具体思路,先贴上代码。

 

#include <cstdio>
#include <cstring>
#include <iostream>
#define INF -2139062144
using namespace std;
int main()
{
    int n,K,kase=0;
    while(scanf("%d%d",&n,&K)&&!(!n&&!K))
    {
        int grid[80][80]= {0};
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=n; ++j)
                scanf("%d",&grid[i][j]);
        int dp[80][80][10][5];
        memset(dp,0x80,sizeof(dp));
        dp[1][0][0][1]=0;
        for(int i=1; i<=n; ++i)
        {
            int v;
            for(int j=1; j<=n; ++j)
            {
                if(grid[i][j]>=0) v=0;
                else v=1;
                for(int k=0; k<=K; ++k)
                {
                    dp[i][j][k+v][1]=max(dp[i][j-1][k][1],dp[i-1][j][k][0]);
                    if(dp[i][j][k+v][1]!=INF) dp[i][j][k+v][1]+=grid[i][j];
                }
            }
            for(int j=n; j>=1; --j)
            {
                if(grid[i][j]>=0) v=0;
                else v=1;
                for(int k=0; k<=K; ++k)
                {
                    dp[i][j][k+v][2]=max(dp[i][j+1][k][2],dp[i-1][j][k][0]);
                    if(dp[i][j][k+v][2]!=INF) dp[i][j][k+v][2]+=grid[i][j];
                }
            }
            for(int j=1; j<=n; ++j)
                for(int k=0; k<=K; ++k)
                    dp[i][j][k][0]=max(dp[i][j][k][1],dp[i][j][k][2]);
        }
        int ans=INF;
        for(int i=0; i<=K; ++i)
            ans=max(dp[n][n][i][0],ans);
        printf("Case %d: ",++kase);
        if(ans==INF) puts("impossible");
        else printf("%d\n",ans);
    }
    return 0;
}


 

你可能感兴趣的:(动态规划)