题解:
第一步:转化题意:
如果我们要取在数组中的一个数。那么它左右相邻的数都没办法取。以此类推,取的第一个数就与第二数不是相邻的,那么题意就转变为:在长度为3*n的数组取n个不相邻的数的最大值。
第二步:
考虑dp做法。
dp[i][j][0]表示:选第i个数时已经选了j个数了。(第三维表示是否选择了第一位)
那么可以从dp[j][i][0]转移过来。
那么转移方程:
dp[i][k][1]=max(dp[j][k-1][1]+slices[i],dp[i][k][1]);
dp[i][k][0]=max(dp[j][k-1][0]+slices[i],dp[i][k][0]);
class Solution {
public:
int maxSizeSlices(vector<int>& slices) {
int dp[505][505][2]={0},n=slices.size()-1;
int m=(n+1)/3;
dp[1][1][0]=slices[1];dp[0][1][1]=slices[0];
int ans=max(slices[0],slices[1]);
for(int i=2;i<n;i++)
{
dp[i][1][0]=slices[i];
for(int j=0;j<i-1;j++)
{
for(int k=2;k<=i/2+1;k++)
{
dp[i][k][1]=max(dp[j][k-1][1]+slices[i],dp[i][k][1]);
dp[i][k][0]=max(dp[j][k-1][0]+slices[i],dp[i][k][0]);
}
}
ans=max(max(dp[i][m][1],dp[i][m][0]),ans);
}
dp[n][1][0]=slices[n];
for(int j=2;j<n-1;j++)
{
for(int k=1;k<=m;k++)
{
dp[n][k][0]=max(dp[j][k-1][0]+slices[n],dp[n][k][0]);
}
}
ans=max(ans,dp[n][m][0]);
return ans;
}
};
时间复杂度为O(n^3);
考虑优化;
dp[i][j]表示枚举到了第i位,选择第j个数了。
转移也很好写出来了
dp[i][j][1]=max(dp[i-1][j][1],dp[i-2][j-1][1]+slices[i]);
dp[i][j][0]=max(dp[i-1][j][0],dp[i-2][j-1][0]+slices[i]);
代码:
class Solution {
public:
int maxSizeSlices(vector<int>& slices) {
int dp[505][505][2]={0};
reverse(slices.begin(),slices.end());slices.push_back(0);
reverse(slices.begin(),slices.end());
int n=slices.size()-1;
dp[1][1][1]=slices[1];dp[2][1][0]=slices[2];
dp[2][1][1]=slices[1];//这一步漏了导致一直wa
int m=n/3,ans=max(slices[1],slices[2]);
for(int i=3;i<n;i++)
{
for(int j=1;j<=m;j++)
{
dp[i][j][1]=max(dp[i-1][j][1],dp[i-2][j-1][1]+slices[i]);
dp[i][j][0]=max(dp[i-1][j][0],dp[i-2][j-1][0]+slices[i]);
}
ans=max(ans,max(dp[i][m][1],dp[i][m][0]));
//cout<<i<<" "<<max(dp[i][2][1],dp[i][2][0])<<endl;
}
dp[n][m][0]=(dp[n-1][m][0],dp[n-2][m-1][0]+slices[n]);
dp[n][m][1]=dp[n-1][m][1];
//cout<<dp[n][m][0]<<endl;
ans=max(ans,max(dp[n][m][0],dp[n][m][1]));
return ans;
}
};
时间复杂度O(n^3)