扣分后的最大得分
题目
给你一个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;
}
};

浙公网安备 33010602011771号