zoukankan      html  css  js  c++  java
  • 【整理】石子合并问题(四边形不等式DP优化)

    有很多种算法:

               1,任意两堆可以合并:贪心+单调队列。

          2,相邻两堆可合并:区间DP    (O(n^3)) )。

          3,相邻,四边形不等式优化DP (O(n^2) )。

          4,相邻,GarsiaWachs算法    (O(nlgn))。

     

    这里实现了第2,3种解法:(个人的区间DP习惯从后面向前面扫)

    看起来第四种还是比较重要的,有空再搞。

     2:暴力DP

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    
    using namespace std;
    const int inf=1000000000;
    int a[110],dp[110][110],sum[110];
    int main()
    {
        int n,i,j,k;
        scanf("%d",&n);
        for(i=1;i<=n;i++) scanf("%d",&a[i]);
        for(i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++) dp[i][j]=inf;
        for(i=1;i<=n;i++) dp[i][i]=0;
        
        for(i=n-1;i>=1;i--)
           for(j=i+1;j<=n;j++)
             for(k=i;k<=j;k++)
                dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1],dp[i][j]);
        printf("%d
    ",dp[1][n]);
        return 0;
    }

    3:优化DP

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #define LL long long
    using namespace std;
    LL min(LL a,LL b){
        if(a<b) return a;return b;
    }
    const LL inf=1000000000000000000;
    LL a[2200],dp[2200][2200],sum[2200];
    LL s[2200][2200],ans=inf; 
    int main()
    {
        LL n,i,j,k;
        scanf("%lld",&n);
        for(i=1;i<=n;i++) {
            scanf("%lld",&a[i]);
            a[i+n]=a[i];
        }
        for(i=1;i<=2*n;i++) sum[i]=sum[i-1]+a[i];
        for(i=1;i<=2*n;i++)
            for(j=1;j<=2*n;j++) 
                dp[i][j]=(i==j?0:inf);
    
        for(i=2*n-1;i>=1;i--)
           for(j=i+1;j<=2*n;j++){
             LL L=s[i][j-1]?s[i][j-1]:i;
             LL R=s[i+1][j]?s[i+1][j]:n+n;
             for(k=L;k<=R;k++){
                    LL  tmp=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];
                    if(dp[i][j]>tmp){
                        dp[i][j]=tmp;
                        s[i][j]=k;
                    }
             }
        }    
        for(i=1;i<=n;i++)
         ans=min(ans,dp[i][i+n-1]);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    在Centos 7下编译openwrt+njit-client
    开博随笔
    Chapter 6. Statements
    Chapter 4. Arrays and Pointers
    Chapter 3. Library Types
    Chapter 2.  Variables and Basic Types
    关于stm32不常用的中断,如何添加, 比如timer10 timer11等
    keil 报错 expected an identifier
    案例分析 串口的地不要接到电源上 会烧掉
    案例分析 CAN OPEN 调试记录 进度
  • 原文地址:https://www.cnblogs.com/hua-dong/p/7819144.html
Copyright © 2011-2022 走看看