关闭

石子合并问题

179人阅读 评论(0) 收藏 举报
分类:
#include "iostream"
#include "algorithm"
#include "fstream"
using namespace std;

/*
参考:http://blog.csdn.net/lyflower/article/details/2150239

minc[i,j]表示将石子i堆到j堆合并的最小得分
maxc[i,j]表时将石子i堆到j堆合并的最大得分
minc[i][j] = min{minc[i][k] + minc[k+1][j] + totalValue(i,j)} i<=k<j
*/

int minc[100][100];
int maxc[100][100];
int a[50];  //每堆石子个数

int total(int i, int j)
{
    return a[j] - a[i-1];
}

int minCost(int n)
{
    memset(minc, 0, sizeof(minc));
    for(int r=2; r<=n; r++)  //问题规模
        for(int i=1; i<=n-r+1; i++)  //区间左端点
        {
            int j = i + r - 1;  //区间右端点
            minc[i][j] = minc[i][i] + minc[i+1][j]; //初始值
            for(int k=i+1; k<j; k++)
            {
                int temp = minc[i][k] + minc[k+1][j];
                if(minc[i][j] > temp)
                    minc[i][j] = temp;
            }
            minc[i][j] += total(i, j);
        }

    //因为是圆排列,所以需要寻找最佳解
    n = (n+1)/2;
    int best = minc[1][n];
    for(int i=2; i<n; i++)
        if(minc[i][i+n-1] && minc[i][i+n-1] < best)
            best = minc[i][i+n-1];
    return best;
}

int max(int a, int b)
{
    return a>b? a:b;
}

int maxCost(int n)
{
    memset(maxc, 0, sizeof(maxc));
    for(int r=2; r<=n; r++)  //问题规模
        for(int i=1; i<=n-r+1; i++)  //区间左端点
        {
            int j = i + r - 1;  //区间右端点
            maxc[i][j] = maxc[i][i] + maxc[i+1][j]; //初始值
            for(int k=i+1; k<j; k++)
            {
                int temp = maxc[i][k] + maxc[k+1][j];
                if(maxc[i][j] < temp)
                    maxc[i][j] = temp;
            }
            maxc[i][j] += total(i, j);
        }

    //因为是圆排列,所以需要寻找最佳解
    n = (n+1)/2;
    int best = maxc[1][n];
    for(int i=2; i<n; i++)
        if(minc[i][i+n-1] && maxc[i][i+n-1] > best)
            best = maxc[i][i+n-1];
    return best;
}

int main()
{
    ifstream fin("stone.txt");
    int n;
    cout  << "输入石子堆数:";
    fin >> n;  cout << n;
    cout << "\n输入各堆中石子数量:\n";
    for(int i=1; i<=n; i++)
    {
        fin >> a[i];
        a[n+i] = a[i];
        cout << a[i] << " ";
    }

    for(i=2; i<=2*n; i++)
        a[i] += a[i-1];

    cout << "\n最小得分:" << minCost(2*n) << endl;
    cout << "最大得分:" << maxCost(2*n) << endl;
    fin.close();
    return 0;
} 

这里写图片描述

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:267517次
    • 积分:9981
    • 等级:
    • 排名:第1697名
    • 原创:758篇
    • 转载:42篇
    • 译文:4篇
    • 评论:104条
    最新评论