扣分後的最大得分
阿新 • • 發佈:2021-10-28
題目
給你一個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; } };