扣分后的最大得分

Leetcode 1937.扣分后的最大得分

题目

给你一个m*n的整数矩阵points(下标从0开始)。一开始你的得分为0,你想最大化从矩阵中得到的分数。
你的得分方式为:每一行中选取一个格子,选中坐标为(r,c)的格子会给你的总得分增加points[r][c] 。
然而,相邻行之间被选中的格子如果隔得太远,你会失去一些得分。对于相邻行r和r+1(其中0 <=r<m-1),选中坐标为(r,c1)和(r+1,c2)的格子,你的总得分减少abs(c1-c2) 。
请你返回你能得到的最大得分。

abs(x)定义为:

  • 如果 x>=0,那么值为x。
  • 如果 x<0,那么值为-x。

题解

其实看到解释abs定义时就感觉有点东西了,因为总不会有人不知道abs的意思吧!
典型动态规划题,我一来就搞了个很朴素的dp公式。

 int f[maxx][maxx];
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++){
               f[0][j]=p[0][j];
               for(int k=0;k<n;k++){
                    f[i][j]=max(f[i][j],p[i][j]+f[i-1][k]-abs(j-k));
               }
            }

哈哈,三重循环,我不死谁死?(即答:被o(n^3)凌虐的电脑)
然后再看一眼题目里的abs。悟了,这就拆,这就拆。

class Solution {
public:
    long long maxPoints(vector<vector<int>>& p) {
        int m=p.size(),n=p[0].size();
        long long f[maxx];
        for(int j=0;j<n;j++) f[j]=p[0][j];
        long long l[maxx],r[maxx];
        for(int i=1;i<m;i++) {
            l[0]=f[0];
            for(int j=1;j<n;j++){//左边
                l[j]=max(l[j-1],f[j]+j);
            }
            r[n-1]=f[n-1]-(n-1);
            for(int j=n-2;j>=0;j--){//右边
                r[j]=max(r[j+1],f[j]-j);
            }
            for(int j=0;j<n;j++)
                f[j]=p[i][j]+max(l[j]-j,r[j]+j);
        }
        long long ans=0;
        for(int j=0;j<n;j++) ans=max(ans,f[j]);
        return ans;
    }
};
posted @ 2021-10-28 18:07  Chilyyy  阅读(40)  评论(0)    收藏  举报