zoukankan      html  css  js  c++  java
  • 前缀和

    一、一维前缀和

    以题  303. 区域和检索 - 数组不可变  为例

    题目的意思就是  

    给定一个整数数组  nums,求出数组从索引 i 到 ji ≤ j)范围内元素的总和,包含 i两点。

    就以这个为出发点,求一个数组给定区间内的和。

    如果数组的大小比较小,那么可以直接暴力求,当数组比较大时,可以采用空间换时间的方法。

    就是设定一个前缀和数组presum,presum[i]存储对应前 i 个数组的和。这样求 i 到 j 的区间和就可以用presum[j]-presum[i]来求

    仅对要求本身的代码:(不是这个303题的)

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn=200+10;
    const int N=10;
    int main()
    {
        int a[maxn];
        int presum[maxn];
        for(int i=1;i<=N;i++)
        {
            scanf("%d",&a[i]);
            //presum[i]=presum[i-1]+a[i];可合写到这里 
        }
        for(int i=1;i<=N;i++)
        {
            presum[i]=presum[i-1]+a[i];//预处理前缀和 
        }
        printf("%d",presum[6]-presum[2]);//求第3个数到第6个数的区间和,注意是前6个数的和减去前2个数的和!! 
        return 0;
    }

    输入1 2 3 4 5 6 7 8 9 10

    输出 18

    对于303这个题,代码如下:(额。。这个题针对输入数据好像没法用前缀和。。。)

    class NumArray {
    public:
        vector<int> array;
        NumArray(vector<int> nums) {
            for(int i=0;i<nums.;i++)
            {
                array.push_back(nums[i]);
            }
        }
        
        int sumRange(int i, int j) {
        int sum=0;
        for(int k=i;k<=j;k++)
        {
            sum+=array[k];
        }
        return sum;
        }
    };

    二、二维数组前缀和

    其实和一维的差不多,就是在求presum[i][j]时,需要这样presum[i][j]=presum[i-1][j]+presum[i][j-1]+presum[i-1][j-1]+a[i][j]

    因为这个求法presum[i-1][j-1]减了两次

    具体看题   轰炸区最优选取   

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=58;
    int main()
    {
        int mp[maxn][maxn];
        int presum[maxn][maxn];
        memset(presum,0,sizeof(presum));//置零 
        int n,k;
        while(cin>>n>>k)
        {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&mp[i][j]);
                presum[i][j]=presum[i-1][j]+presum[i][j-1]-presum[i-1][j-1]+mp[i][j];//预处理前缀和 
            }
        }
        int sum,ans=0;
        for(int i=k;i<=n;i++)
        {
            for(int j=k;j<=n;j++)
            {
                sum=presum[i][j]-presum[i-k][j]-presum[i][j-k]+presum[i-k][j-k];//得到某区域的和的方法相同 
                ans=max(ans,sum);//取和最大的那块区域 
            }
        }
        cout<<ans<<endl;
    }
        return 0;
    }
  • 相关阅读:
    windown 下最简单的安装mysql方式
    mac 重置mysql密码
    开发过程中用到的软件
    Springboot 热部署问题。亲测可用。
    时间转换~
    java 流转换BASE64的一些问题
    SpringMvc 使用Thumbnails压缩图片
    SpringMVC Get请求传集合,前端"异步"下载excel 附SpringMVC 后台接受集合
    Mac 笔记本 开发日记
    RabbitMQ入门:路由(Routing)
  • 原文地址:https://www.cnblogs.com/theshorekind/p/14320422.html
Copyright © 2011-2022 走看看