NYOJ 737 (Stone Merging)

This question is a DP question, the core idea is as follows:

An interval must be composed of two sub-intervals in this interval (the two sub-intervals are complementary, that is, the sum of these two intervals is equal to the large interval),

So we enumerate all the cases and take the maximum value. Because at first it was impossible to choose from 2 piles of stones, and when the number is large, you can choose the best, reflecting the advantages of DP.

DP[ i ] [ j ] represents the optimal merged value for the interval i to j.

Then the transfer equation from the above idea is as follows:

dp[ i ][ j ] = min(  dp[ i ][ j ], dp[ i ][ k ] + dp[k + 1][ j ] + sum[ i ][ j ] ) (i <= k <= j - 1)。

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
int n, s[205][205], a[205], f[205][205];

intmain ()
{
    while(scanf("%d", &n) != EOF)
    {
        memset(s, 0, sizeof s );
        memset(a, 0, sizeof a );
        memset(f, 0, sizeof f );
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        for(int i = 1; i <= n; i++)
        {
            for(int j = i; j <= n; j++)
            {
                f[i][j] = 0x3f3f3f3f ; // Initial value is assigned infinite 
                for ( int k = i; k <= j; k++ )
                    s[i][j] = s[i][j] + a[k];
            }
        }
        for(int i = 1; i <= n; i++)
            f[i][i] = 0 ; // The initial value of itself is 0 
        for ( int i = 1 ; i < n; i++ )
        {
            for(int j = 1; j <= n-i; j++)
            {
                for(int k = j; k <= i + j - 1; k++)
                {
                    if(f[j][i+j] > f[j][k] + f[k+1][i+j]+s[j][i+j])
                        f[j][i+j] = f[j][k] + f[k+1][i+j]+s[j][i+j];
                }
                printf("f[%d][%d] = %d\n", j, i+j, f[j][i+j]); 
            }
        }
        printf("%d\n", f[1][n]);
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325144268&siteId=291194637