题目:
分析:
- 之前做过
- 没做过也应该能看出是区间dp。
- 只用增加一个维度,表明从左还是从右。能拿的个数由当前长度简洁给出了。
不用给定方向,dp的维度为2时,代码T了:
class Solution {
public:
vector<vector<int> > A;
int f(int a,int b,int k,vector<int>& cardPoints)
{
if(k==0) return 0;
if(A[a][b]!=-1) return A[a][b];
A[a][b]=0;
A[a][b]=max(f(a+1,b,k-1,cardPoints)+cardPoints[a],f(a,b-1,k-1,cardPoints)+cardPoints[b]);
return A[a][b];
}
int maxScore(vector<int>& cardPoints, int k) {
vector<int> v(cardPoints.size(),-1);
for(int i=0;i<cardPoints.size();i++) A.push_back(v);
return f(0,cardPoints.size()-1,k,cardPoints);
}
};
当我在想dp中给定方向和不给定方向是差了什么的时候,想想其实复杂度好像不应该差什么。
于是想到了博弈论中用到的前缀和来优化。
然后又想到了dp其实都不用啊,之前枚举就可以啦啊。
线性复杂度。
class Solution {
public:
int maxScore(vector<int>& cardPoints, int k) {
int ans=0;
for(int i=0;i<k;i++)
{
ans+=cardPoints[i];
}
int c=ans;
for(int i=0;i<k;i++)
{
c=c+cardPoints[cardPoints.size()-1-i]-cardPoints[k-1-i];
ans=max(c,ans);
}
return ans;
}
};