题目:
分析:
显然的dp,
改题,分解成k部分的代码:
class Solution {
public:
int A[501][500];
int f(vector<int> v,int c,int k)
{
if(A[c][k]!=-(1<<30)) return A[c][k];
if(k==1)
{
int maxx=-(1<<30);
for(int i=c;i<v.size();i++) maxx=max(maxx,v[i]);
A[c][k]=maxx*(v.size()-c);
cout<<c<<" "<<k<<" "<<A[c][k]<<endl;
return A[c][k];
}
int maxx=-(1<<30);
for(int i=c;i<=v.size()-k;i++)
{
maxx=max(maxx,v[i]);
A[c][k]=max(A[c][k],(i-c+1)*maxx+f(v,i+1,k-1));
if(A[c][k]==90) cout<<"??"<<i<<" "<<endl;
}
cout<<c<<" "<<k<<" "<<A[c][k]<<endl;
return A[c][k];
}
int maxSumAfterPartitioning(vector<int>& v, int k) {
for(int i=0;i<v.size();i++)
{
for(int j=0;j<=k;j++) A[i][j]=-(1<<30);
}
//从i开始包括i,其后面的,分成k组。
return f(v,0,k);
}
};
自顶向下的dp超时:
int A[501][500];
int f(vector<int> v,vector<int> &A,int x,int k)
{
if(x==v.size()) return 0;
if(A[x]!=-(1<<30)) return A[x];
if(x==v.size()-1) return v[x];
int maxx=-(1<<30);
for(int i=x;i<min(k+x,v.size());i++)
{
maxx=max(maxx,v[i]);
A[x]=max(A[x],(i-x+1)*maxx+f(v,A,i+1,k));
}
return A[x];
}
int main()
{
vector<int> v;
int k;
vector<int> A(v.size(),-(1<<30));
return f(v,A,0,k);
}
改进版dp,不用回溯即可啊!
class Solution {
public:
int maxSumAfterPartitioning(vector<int>& v, int k) {
vector<int> A(v.size(),-(1<<30));
//A[i]表示到i为止的最大值。
A[0]=v[0];
for(int i=1;i<v.size();i++)
{
for(int j=max(0,i-k+1);j<=i;j++)
{
int maxx=-(1<<30);
for(int c=j;c<=i;c++) maxx=max(maxx,v[c]);
if(j!=0)
A[i]=max(A[i],A[j-1]+(i-j+1)*maxx);
if(j==0)
A[i]=max(A[i],(i-j+1)*maxx);
}
}
return A[v.size()-1];
}
};