码迷,mamicode.com
首页 > 其他好文 > 详细

FOJ 1319 Blocks of Stones[ 区间 ]

时间:2015-01-16 20:59:29      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

Blocks of Stones

Description

There are n blocks of stones in a line laying on the ground. Now you are to merge these blocks of stones together with the restriction that you can only merge the neighbouring blocks each time. The score you get for each merging is the number of stones the new blocks has.

Before merging, you are allowed to swap a neighbouring block. You are to calculate the minimal score you will get during the merging process, and the swap position.

Input

There are multiple test cases. For each case, the first line contains a integer n(n<=100), representing the number of blocks. The second line contains n integers, representing number of stones in each blocks

Output

For each case, output 2 lines. The first line contains a single integer, representing the minimal score. The second line contains to integers in the form "(k,k+1)", representing the swap position. If there is more than one swap position which can be the minimal score, output the one with the largest k. You should note that : If swap is not needed output "(0,1)".

Sample Input

3
2 5 1
3
1 2 5

Sample Output

11(2,3)11(0,1)

思路:

    阶段:以归并石子的长度为阶段,一共有n-1个阶段。
    状态:每个阶段有多少堆石子要归并,

          当归并长度为2时,有n-1个状态;
          当归并长度为3时,有n-2个状态;
          当归并长度为n时,有1个状态。
    决策:当归并长度为2时,有1个决策;

          当归并长度为3时,有2个决策;
          当归并长度为n时,有n-1个决策。 


代码:

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
const int INF = 1 << 30;
const int N = 205;

int dp[N][N];
int sum[N];
int a[N];

int getMinval(int a[],int n)
{
    for(int i=0;i<n;i++)
        dp[i][i] = 0;
    for(int v=1;v<n;v++)
    {
        for(int i=0;i<n-v;i++)
        {
            int j = i + v;
            dp[i][j] = INF;
            int tmp = sum[j] - (i > 0 ? sum[i-1]:0);
            for(int k=i;k<j;k++)
                dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j] + tmp);
        }
    }
    return dp[0][n-1];
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        sum[0] = a[0];
        for(int i=1;i<n;i++)
            sum[i] = sum[i-1] + a[i];
        int x=0,y=1;
        int flag=1;
        int ans=getMinval(a,n);
        for(int i=0;i<n-1;i++)
        {
            sum[i]=sum[i]-(a[i]-a[i+1]);
            int tmp=getMinval(a,n);
            if(flag)
            {
                if(tmp<ans)
                {
                    ans=tmp;
                    x=i+1;
                    y=i+2;
                    flag=0;
                }
            }
            else{
                if(tmp<=ans)
                {
                    ans=tmp;
                    x=i+1;
                    y=i+2;
                }
            }

            sum[i]=sum[i]+(a[i]-a[i+1]);
        }
        printf("%d\n(%d,%d)\n",ans,x,y);
    }
    return 0;
}



FOJ 1319 Blocks of Stones[ 区间 ]

标签:

原文地址:http://blog.csdn.net/code_or_code/article/details/42781031

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!