LeetCode 1388. 3N块披萨 线性dp

LeetCode 1388. 3N块披萨 线性dp_第1张图片

题解:

第一步:转化题意:
如果我们要取在数组中的一个数。那么它左右相邻的数都没办法取。以此类推,取的第一个数就与第二数不是相邻的,那么题意就转变为:在长度为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<
        }
        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<
        ans=max(ans,max(dp[n][m][0],dp[n][m][1]));
        return ans;
    }
};

时间复杂度O(n^3)

你可能感兴趣的:(dp,leetcode,动态规划,算法)