zoukankan      html  css  js  c++  java
  • 石子归并

    有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得总合并代价达到最小。

    第一行一个整数n(n<=100)

    第二行n个整数w1,w2...wn  (wi <= 100)

    dp[i][j]表示合并i到j之间的石头

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

    如果只有两堆的时候,dp[i][i+1]=sum(i,i+1)

    如果把三堆合起来,就是dp[i][i+2]=min(dp[i][i+1],dp[i+1][i+2])+sum(i,i+2)

    以此推到n堆的时候就行了,O^3,貌似看到别人说可以四边形优化??不懂= =下次遇到要优化的再回来看看

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    typedef double db;
    #define X first
    #define Y second
    #define mp(a,b) make_pair(a,b)
    #define pb push_back
    #define sd(x) scanf("%d",&(x))
    #define Pi acos(-1.0)
    #define sf(x) scanf("%lf",&(x))
    #define ss(x) scanf("%s",(x))
    #define maxn 50005
    const int inf=0x3f3f3f3f;
    const ll mod=1000000007;
    int sum[105];
    int dp[105][105];
    int main()
    {
    #ifdef local
        freopen("in","r",stdin);
        //freopen("out","w",stdout);
        int _time=clock();
    #endif
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>sum[i];
            sum[i]+=sum[i-1];
        }
        for(int v=1;v<n;v++)
        {
            for(int i=1;i<=n-v;i++)
            {
                dp[i][i+v]=inf;
                int j=i+v;
                int tmp=sum[j]-sum[i-1];
                for(int z=i;z<j;z++)
                {
                    dp[i][j]=min(dp[i][j],dp[i][z]+dp[z+1][j]+tmp);
                }
            }
        }
        cout<<dp[1][n]<<endl;
    #ifdef local
        printf("time: %d
    ",int(clock()-_time));
    #endif
    }
    View Code
  • 相关阅读:
    jQuery事件
    php学习注意事项
    取消php上传2M的限制(windows服务器)
    PHP编程值得注意的细节
    jQuery load()方法特殊用法!
    PHP显示乱码和apache内部编码问题的解决
    定制Apache索引样式
    这么长时间也没有人看看我
    加载php5apache2_2.dll失败的处理方法
    WinXP下的ApachePHPMySQL安装和配置
  • 原文地址:https://www.cnblogs.com/scau-zk/p/5634395.html
Copyright © 2011-2022 走看看