算法基础之石子合并

石子合并

  • 核心思想: 区间dp

    • 集合定义 : f[i][j]表示将[i,j] 合并的最小代价

    • 集合计算 : 枚举 i<=k<=j 将f[i][j] (因为i到j是连续的)分为 **f[i][k] + f[k+1][j] + (s[j] – s[i–1])**三部分

      • 算法基础之石子合并_第1张图片
    •   #include
        #include
        #include
        
        using namespace std;
        const int N = 310;
        
        int f[N][N];
        int s[N];  //前缀和数组 用于求 i -- j 总和
        int n;
        
        int main()
        {
            cin>>n;
            for(int i=1;i<=n;i++) cin>>s[i] , s[i] += s[i-1];  //求前缀和
            
            for(int len = 2;len<=n;len++)  //遍历所有区间长度 长度为1没有代价 =0 不用初始化
            {
                for(int i=1;i + len -1 <=n; i++)  //区间左端点遍历 直到右端点 =n
                {
                    int j = i + len -1;  //右端点
                    f[i][j] = 1e8;  //将该区间代价初始化无穷大  否则min永远是0
                    for(int k=i;k<=j;k++)  //遍历区间内部
                    {
                        f[i][j] = min(f[i][j] , f[i][k] + f[k+1][j] + s[j] - s[i-1]);
                    }
                }
            }
            //回归定义 f[1][n]为1--n的最小代价
            cout<<f[1][n];
        }
      

你可能感兴趣的:(算法,数据结构,c++,图论,开发语言)