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
  • 相关阅读:
    DB2数据库基础
    mysqldump 备份数据库脚本
    Windows Server 2012 R2 卸载IE浏览器
    mysqlpump 和 mysql_config_editor测试
    Linux 修改时区
    PowerShe 消息提示框测试
    Python使用libsvm的“ImportError: No module named svmutil”问题
    常见的机器学习&数据挖掘知识点
    [猜你喜欢]冠军“yes,boy!”分享,含竞赛源代
    用户人品预测大赛获奖团队分享
  • 原文地址:https://www.cnblogs.com/scau-zk/p/5634395.html
Copyright © 2011-2022 走看看