HDU 1078 FatMouse and Cheese

简单DP

因为一定是小的数字推到大的数字,所以排序,转化成线性的DP

#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=100+10;
int a[maxn][maxn],b[maxn][maxn];
int n,k;
struct X
{
    int r,c;
    int val;
} s[maxn*maxn];

int dp[maxn*maxn];

bool cmp(const X&a,const X&b)
{
    return a.val<b.val;
}

int main()
{
    while(~scanf("%d%d",&n,&k))
    {
        if(n==-1&&k==-1) break;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                s[i*n+j].r=i;
                s[i*n+j].c=j;
                scanf("%d",&s[i*n+j].val);
                a[i][j]=s[i*n+j].val;
            }
        }
        sort(s,s+n*n,cmp);
        for(int i=0;i<n*n;i++) b[s[i].r][s[i].c]=i;
        for(int i=0;i<n*n;i++) dp[i]=-1;

        int pos;
        for(int i=0;i<n*n;i++)
            if(s[i].r==0&&s[i].c==0)
                {pos=i;break;}

        dp[pos]=s[pos].val;
        int ans=dp[pos];

        for(int i=pos;i<n*n;i++)
        {
            if(dp[i]==-1) continue;
            int R=s[i].r;
            int C=s[i].c;
            for(int j=R-k;j<=R+k;j++)
            {
                if(j<0||j>=n) continue;
                if(a[j][C]<=a[R][C]) continue;
                if(dp[i]+a[j][C]>dp[b[j][C]])
                {
                    dp[b[j][C]]=dp[i]+a[j][C];
                    ans=max(ans,dp[b[j][C]]);
                }
            }

            for(int j=C-k;j<=C+k;j++)
            {
                if(j<0||j>=n) continue;
                if(a[R][j]<=a[R][C]) continue;
                if(dp[i]+a[R][j]>dp[b[R][j]])
                {
                    dp[b[R][j]]=dp[i]+a[R][j];
                    ans=max(ans,dp[b[R][j]]);
                }
            }
        }
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zufezzt/p/5144277.html