zoukankan      html  css  js  c++  java
  • 洛谷P1043(水题题解)

    首先先上大佬DP法的AC代码(原链接

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,f1[110][110][110],f2[110][110][110],a[110],sum[110];
    int mod(int x){
        return (x%10+10)%10;
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++){cin>>a[i];sum[i]=sum[i-1]+a[i];}
        for(int i=1;i<=n;i++){a[i+n]=a[i],sum[i+n]=sum[i]+sum[n];}
        memset(f2,127,sizeof(f2));//f2记录的是最小值 所以要初始化为极大值
        for(int i=1;i<=2*n;i++){
            for(int j=i;j<=2*n;j++){
                f1[i][j][1]=f2[i][j][1]=mod(sum[j]-sum[i-1]);//预处理每段的值
            }
        }
        for(int l=1;l<=n;l++){//区间长度
            for(int i=1,j=i+l-1;j<=2*n;i++,j++){//左右端点
                for(int h=2;h<=m;h++){//段数
                    for(int k=i+h-1;k<j;k++){//短点
                        f1[i][j][h]=max(f1[i][j][h],f1[i][k][h-1]*mod(sum[j]-sum[k]));
                        f2[i][j][h]=min(f2[i][j][h],f2[i][k][h-1]*mod(sum[j]-sum[k]));
                    }
                }
            }
        }
        int maxn=0,minn=0x7fffffff;
        for(int i=1;i<=n;i++){//找答案啦~~~
            maxn=max(maxn,f1[i][i+n-1][m]);
            minn=min(minn,f2[i][i+n-1][m]);
        }
        cout<<minn<<endl<<maxn;
    }

    大佬思路

    设状态

    DP的套路就是题目问什么就设什么,然后这有是一道区间DP经典题

    所以我们设f[i][j][h]表示从i到j分成h段的最大最小值

    转移方程

    由状态我们可以得出转移方程:

    f[i][j][h]=max/min(f[i][j][h],f[i][k][h-1]*sum)f[i][j][h]=max/min(f[i][j][h],f[i][k][h1]sum)

    先枚举区间长度

    从正常的区间DP模板我们知道应该

    为什么呢:

    如果我们先枚举i,j

    比如说i=1,j=10,k=5时

    f[1][5][h]并没有被处理出来这样就错了

    再枚举左右端点

    这个好理解,区间DP嘛

    再是枚举段数

    这个也很好理解 要更新答案嘛

    最后枚举短点并更新答案

  • 相关阅读:
    spring boot自动配置
    servlet类与Spring Controller类的关系
    Junit中的setup和teardown方法
    dependency的scope
    mapper的namespace
    mybatis缓存
    Ehcache(05)——缓存的查询
    Ehcache(04)——设置缓存的大小
    Ehcache(03)——Ehcache中储存缓存的方式
    Ehcache(02)——ehcache.xml简介
  • 原文地址:https://www.cnblogs.com/lifeisabadword/p/11722838.html
Copyright © 2011-2022 走看看