zoukankan      html  css  js  c++  java
  • P1115 最大子段和&P1719 最大加权矩形

    上接:DP&图论 DAY 1 上午

    这两个题本质是一个亚子,所以放一起啦
    DPDPDPDPDPDPDPDP

    P1115 最大子段和

    题解

     因为题目要求的是一段连续的区间,所以前缀和搞暴力???

    我们设置数组 f[ i ] 表示以 a[ i ] 结尾的最大连续子段和

    那么转移??? 

    1.接着上一段,继续构成一段连续的子段 continue the old life

    2.自成一段  和过去 say goodbye

    转移方程: 

    ans记录最大值就好啦

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int maxn=2e5+10;
    int n,ans;
    int a[maxn];
    int f[maxn];
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
          a[i]=read();
        f[0]=0;f[1]=a[1];
        ans=a[1];
        for(int i=1;i<=n;i++)
        {
            f[i]=max(f[i-1]+a[i],a[i]);
            ans=max(ans,f[i]);
        }
        printf("%d
    ",ans);
        
        return 0;
    }

    P1719 最大加权矩形

    题解

    其实这个题就是上一个的变式,我们只需要把本题的二维转变成一维就好啦!

    考虑枚举子矩阵的上下界

    确定了上下界,就缩成了一维,此时只需要算 “该行” ,的最大 f[ ] 就好啦!

    解释一下数组:

     a[ i ][ j ] :读入给出的矩阵

    sum[ i ][ j ] :第 j 列,前 i 行的前缀和

    其实这里的 就相当于上一个题的

    代码

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    
    using namespace std;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int maxn=125;
    int n,ans=-128;
    int a[maxn][maxn],sum[maxn][maxn],f[maxn];
    
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
           for(int j=1;j<=n;j++)
               a[i][j]=read(),sum[i][j]=sum[i-1][j]+a[i][j];
    
        for(int i=1;i<=n;i++)
          for(int j=i;j<=n;j++)   //枚举上下界 i~j 
          {
              memset(f,0,sizeof(f));
              for(int k=1;k<=n;k++)   //DP
                f[k]=max(f[k-1]+(sum[j][k]-sum[i-1][k]),(sum[j][k]-sum[i-1][k])),
                ans=max(ans,f[k]);
          }
        
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    客户端组建调用
    串口开发
    C/C++,系统知识考点
    API进程线程函数
    做WEB2.0网站可以参考的十九条规则
    javascript中动态添加事件!!
    常用正则表达式收集!
    CuteChat for Community Server 2.0 beta 3!
    发现一个下载.Text Skin 的好网站.
    如何控制Linux终端打印字符颜色和位置
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11355924.html
Copyright © 2011-2022 走看看