zoukankan      html  css  js  c++  java
  • P1880 [NOI1995]石子合并(四边形不等式优化DP)

    题目地址


    状态设计:

    • fmax[i][j]:从第i堆合并到第j堆的最大得分.
    • fmin[i][j]:从第i堆合并到第j堆的最小得分.
    • s[i][j]:fmin[i][j]被更新时所使用的中间点k.

    易错点:

    • 由于有环,所以需要断链加一倍.
    • fmax[i][j]直接使用贪心转移即可.
    • 枚举第一维时,由于需要用到i和i+1,需要倒序循环.(即从2*n-1到1)

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int MAXN=205,INF=0x3f3f3f3f;
    int a[MAXN],sum[MAXN];
    int fmin[MAXN][MAXN],fmax[MAXN][MAXN],s[MAXN][MAXN];
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            a[i+n]=a[i];
            sum[i]=sum[i-1]+a[i];
            s[i][i]=i;
        }
        for(int i=n+1;i<=2*n;i++){
            sum[i]=sum[i-1]+a[i];
            s[i][i]=i;
        }
        for(int i=2*n-1;i;i--)
            for(int j=i+1;j<=2*n;j++){//
                int bestK=0,minCost=INF;
                fmax[i][j]=max(fmax[i][j-1],fmax[i+1][j])+sum[j]-sum[i-1];
                for(int k=s[i][j-1];k<=s[i+1][j];k++){
                    int nowCost=fmin[i][k]+fmin[k+1][j]+(sum[j]-sum[i-1]);
                    if(nowCost<minCost){
                        minCost=nowCost;
                        bestK=k;
                    }
                }
                s[i][j]=bestK;
                fmin[i][j]=minCost;
            }
        int aMax=-INF,aMin=INF;
        for(int i=1;i<=n;i++){
            aMax=max(aMax,fmax[i][i+n-1]);
            aMin=min(aMin,fmin[i][i+n-1]);
        }
        printf("%d
    %d",aMin,aMax);
        return 0;
    }
  • 相关阅读:
    Md5
    hdu 2569 彼岸
    调用系统相机相冊
    白盒測试
    HDU 1501
    IOS常见错误分析解决(一直更新) 你值得收藏-综合贴
    读“程序猿生存定律”笔记
    Halcon导出的cpp, VC++环境配置
    POJ 1260 Pearls (动规)
    hdoj-1856-More is better【并查集】
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680549.html
Copyright © 2011-2022 走看看