【合并石子——区间DP】

题目

【合并石子——区间DP】_第1张图片

代码

#include 
using namespace std;
const int N = 310;
const int inf = 0x3f3f3f3f;
int f[N][N][3];
int s[N];
int w[N][N], c[N][N];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int n;
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> s[i], s[i] += s[i-1];
    
    memset(f, 0x3f, sizeof f);
    memset(w, 0x3f, sizeof w);
    memset(c, 0x3f, sizeof c);
    for(int i = 1; i <= n; i++)
    {
        int col;
        cin >> col;
        f[i][i][col] = 0;
        w[i][i] = 0;
        c[i][i] = 1;
    }
    
    for(int len = 2; len <= n; len++)
    {
        for(int l = 1; l + len - 1 <= n; l++)
        {
            int r = l + len - 1;
            for(int k = 0; k < 3; k++)
            {
                int ans = inf;
                for(int m = l; m < r; m++)
                {
                    if(f[l][m][k] < inf && f[m+1][r][k] < inf)
                        ans = min(ans, f[l][m][k] + f[m+1][r][k] + s[r] - s[l-1]);
                }
                
                if(ans < inf)
                {
                    c[l][r] = 1;
                    w[l][r] = min(w[l][r], ans);
                    f[l][r][(k + 1) % 3] = ans;
                }
            }
            
            for(int m = l; m < r; m++)
            {
                if(c[l][r] > c[l][m] + c[m+1][r])
                {
                    c[l][r] = c[l][m] + c[m+1][r];
                    w[l][r] = w[l][m] + w[m+1][r];
                }
                else if(c[l][r] == c[l][m] + c[m+1][r])
                    w[l][r] = min(w[l][r], w[l][m] + w[m+1][r]);
            }
        }
    }
    cout << c[1][n] << ' ' << w[1][n];
}

你可能感兴趣的:(蓝桥杯,算法)