• UESTC 886 方老师金币堆 --合并石子DP


    环状合并石子问题。

    环状无非是第n个要和第1个相邻。可以复制该行石子到原来那行的右边即可达到目的。

    定义:dp[i][j]代表从第i堆合并至第j堆所要消耗的最小体力。

    转移方程:dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum[i][j]);

    复杂度:O(n^3)。

    可考虑四边形优化。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define Mod 1000000007
    using namespace std;
    #define N 207
    
    int sum[N],a[N];
    int dp[N][N],n;
    
    int SUM(int i,int j)
    {
        return sum[j]-sum[i-1];
    }
    
    int DP(int l,int r)
    {
        if(dp[l][r] != -1)
            return dp[l][r];
        if(l == r)
            dp[l][r] = 0;
        else
            dp[l][r] = Mod;
        if(l<=n&&r<=n)
            return dp[l][r] = dp[l+n][r+n];
        for(int k=l;k<r;k++)
        {
            int cost = DP(l,k)+DP(k+1,r)+SUM(l,r);
            dp[l][r] = min(dp[l][r],cost);
        }
        return dp[l][r];
    }
    
    int main()
    {
        int i,j;
        while(scanf("%d",&n)!=EOF)
        {
            sum[0] = 0;
            for(i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                a[n+i] = a[i];
                sum[i] = sum[i-1]+a[i];
            }
            for(i=n+1;i<=2*n;i++)
                sum[i] = sum[i-1]+a[i];
            memset(dp,-1,sizeof(dp));
            for(i=2*n;i>=1;i--)
                for(j=i;j<=2*n;j++)
                    DP(i,j);
            int res = Mod;
            for(i=1;i<=n;i++)
                res = min(res,DP(i,i+n-1));
            printf("%d
    ",res);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    JSP页面间传递参数
    JSP获取当前日期时间
    jsp实现套打(发票打印)
    iframe
    HTTP状态码及含义大全
    标签 -- HTML内联框架
    jstl fmt标签详解
    button和submit的区别及使用js实现页面跳转的方式
    Idea SpringBoot 启动Eurka 报错,提示端口被占用
    CodeSmith 破解
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3762756.html
Copyright © 2020-2023  润新知