• 石子合并问题


    有若干堆石子,每次只能合并相邻石子堆,每次合并的开销是两堆石子总和。求合并所有石子的最小开销。

    首先有一个算法叫GarsiaWachs。这个算法思想是,当有三堆石子 a,b,c,其合并开销有两种:先合并ab,(a+b)+((a+b)+c),先合并bc,(b+c)+((b+c)+a)=>a,c即判断a和c的大小关系。当a<c,就应该先合并ab。故我们从左向右遍历是否有a<c,有的话就合并ab。然后把它插到左边比它大的第一个数右边(这个操作不会影响答案,大家可以自己证明以下)。反复上述操作,最后结果就是最佳方案后的一堆石子了。为了编码方便,我们一般把数组的0和n+1置为inf(石子堆编号从1~n)。

    据说可以用平衡树优化,等我去看平衡树再来更新一波。

     
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    using namespace std;
    const int inf=9999999;
    int main(int argc, char *argv[])
    {
        cin.sync_with_stdio(false);
        int n;
        int num[205];
        int dp[205];
        while(cin>>n)
        {
            num[0]=num[n+1]=inf;
            for(int i=1;i<=n;i++)
                cin>>num[i];
            int ans=0;
            while(n!=1)
            {
                //cout<<n<<endl;
                for(int i=1;i<=n;i++)
                {
                    if(num[i-1]<=num[i+1])
                    {
                        //cout<<num[i-1]<<' '<<num[i+1]<<endl;
                        num[i-1]+=num[i];
                        ans+=num[i-1];
                        for(int j=i+1;j<=n;j++)
                            num[j-1]=num[j];
                        num[n]=inf;
                        n--;
                        int temp=num[i-1];
                        for(int j=i-1;j>0;j--)
                        {
                            if(num[j-1]<temp)
                                num[j]=num[j-1];
                            else
                            {
                                num[j]=temp;
                                break;
                            }
                        }
                       
                        break;
                    }
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
            

    还有种算法是基于动态规划的,如果我们要合并i~j堆石子,其开销设为dp[i][j],dp[i][j]=min(dp[i+1][k]+dp[k+1][j]+sum(i,j)) (i<=k<=j)。当区间小到321我们就可以直接做出决策了。

  • 相关阅读:
    web api post/put空值问题以及和angular的冲突的解决
    大话数据结构-图
    大话数据结构-树
    大话数据结构-栈与队列
    大话数据结构-线性表
    redis发布订阅、HyperLogLog与GEO功能的介绍
    redis使用管道pipeline提升批量操作性能(php演示)
    redis设置慢查询日志
    Laravel5.5配置使用redis
    Redis数据类型的常用API以及使用场景
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/6696553.html
Copyright © 2020-2023  润新知