HRBUST - 1818 - 石子合并问题--直线版 (区间dp)

题意:

相邻石堆可以合并,每次合并花费为石子数和,问最终合并为一堆时的花费最少和最多分别是多少

思路:

先枚举区间长度,在枚举端点。端点将区间分为两个,然后合并。

dpn[i][j] = min(dpn[i][j],dpn[i][k] + dpn[k+1][j]+sum[j]-sum[i-1]);

表示 在该长度内任意两个区间合并所求的最小值。

#include 
#include 
using namespace std;
const int maxn = 110;
const int inf = 0x3f3f3f3f;
int dpn[maxn][maxn],dpx[maxn][maxn];
int sum[maxn];
int n;
void init()
{
    memset(dpn,inf,sizeof dpn);
    memset(dpx,0,sizeof dpx);
    for(int i = 0; i  <= n; i++)
    {
        dpn[i][i] = 0;
    }
    sum[0] = 0;
}
int main()
{
    ios::sync_with_stdio(0);
    while(cin>>n)
    {
        init();
        for(int i =1; i <= n; i++)
        {
            cin>>sum[i];
            sum[i] += sum[i-1];
        }
        for(int len = 2; len <= n; len++)
        {
            for(int i = 1, j = len; j <= n; j++,i++ )
            {
                for(int k = i; k < j; k++)
                {
                    dpn[i][j] = min(dpn[i][j],dpn[i][k] + dpn[k+1][j] + sum[j] - sum[i-1]);
                    dpx[i][j] = max(dpx[i][j],dpx[i][k] + dpx[k+1][j] + sum[j] - sum[i-1]);
                }
            }
        }
        cout<

 

你可能感兴趣的:(ACM解题记录,dp)