zoukankan      html  css  js  c++  java
  • 最大整数NYOJ 44 字串和 370 巧克力 (最大连续字串和问题)

    间时紧张,先记一笔,后续优化与完善。

        

    子串和

    间时制约: 5000 ms  |  内存制约: 65535 KB
    难度: 3

        

     
    述描
    给定一整型数列{a1,a2...,an},找出续连非空子串{ax,ax+1,...,ay},使得该子列序的和最大,其中,1<=x<=y<=n。
     
    输入
    第一行是一个整数N(N<=10)示表试测据数的组数)
    每组试测据数的第一行是一个整数n示表列序中共有n个整数,随后的一行里有n个整数I(-100=<I<=100),示表数列中的有所素元。(0<n<=1000000)
    输出
    对于每组试测据数输出和最大的续连子串的和。
    样例输入
    1
    5
    1 2 -1 3 -2
    
    样例输出
    5

        一维的字串和问题,空话不说直接贴最优码代

    #include<stdio.h>
    int main()
    {
    	int n,m,i,max,sum;
    	scanf("%d",&n);
    	while(n--)
    	{
    		max=0;
    		scanf("%d",&m);
    		scanf("%d",&sum);
    		max=sum;
    		while(--m)
    		{
    			scanf("%d",&i);
    			if(sum<0) sum=i;
    			else sum+=i;
    			if(sum>max) max=sum;
    		}
    		printf("%d\n",max);
    	}
    }

        核心码代为

    if(sum<0) sum=i;
    else sum+=i;
    if(sum>max) max=sum;

        面下绍介二维的字串和,其中心思想就是转化为一维的组数

        

        

    巧克力

    间时制约: 4000 ms  |  内存制约: 65535 KB
    难度: 2

        

     
        每日一道理
    微笑,是春天里的一丝新绿,是秋日里的一缕阳光,是骄阳下的一片浓荫,是冬雪中的一株梅红……微笑着去面对吧,你会感到人生是那样的温馨与甜蜜!
    述描

    布欧可以把人酿成巧克力吃了来增长他的能量,也有可能少减。

    当初布欧变了n*m个巧克力,并把巧克力排成一个n*m的矩形,当初布欧想选择一个子矩形,把这个子矩形吃了来增长他的能量,可他不晓得选哪个才能使他的能量增长值p最大,布欧也可以选择一个都不吃,这样p = 0

    当初布欧要你诉告他p的最大值,不然他就先把你酿成巧克力吃了!

     

     
    输入
    第一行:一个整数T 代表试测个数,
    接着T组试测据数。

    对每组试测据数:
    第一行:n m 两个整数
    接着n行每行m个格空离隔的整数a(i,j)代表对应巧克力的能量值(注意可是以正数,吃了能量少减)

    1<=n,m<=300
    -1000<= a(i,j) <= 1000
    输出
    T行
    每行一个整数 p
    样例输入
    3
    3 3
    1 -1 4
    2 -2 3
    3 -10 1
    3 3
    -1 -1 -1
    -1 -1 -1
    -1 -1 -1
    3 3
    1 1 -10
    -1 1 -10
    1 1 -10
    样例输出
    8
    0
    4
    提示
    请应用scanf输入。
    第一组据数吃
    4
    3
    1
    第二组据数一个也不吃
    第三组据数吃
    1 1
    -1 1
    1 1

    面前已说过了,关键是怎么转化为一维的,

        1,遍历二维组数,把每一个位置的值数更新为括包他和他面下的有所数的和;

        例如

        

    1 -1 4
    2 -2 3
    3 -10 1

        更新过后为

        

    6 -13 8
    5 -12 4
    3 -10 1

        

        2,这样每一行都相当于一维组数了,每一行都求一次最大字串和,录记最大的;

        3,从第一行开始,到第n行,拿他的 每一列 分离减去他面下每一行的对应列,这样你会失掉一个新的一维组数,一样求最大续连子串和,每次与面前最大和比拟,取最大的;

        经过这三步,你会失掉一个最大的字串和,就是你要找的结果

        

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cmath>
    #include <map>
    #define FLAG 1
    using namespace std;
    int a[305][305];
    int b[305];
    int maxsum(int *p,int n)
    {
    
        int i,sum,maxi;
        sum=maxi=0;
        for(i=0;i<n;i++)
        {
            if(sum<0)sum=p[i];
            else sum+=p[i];
            if(sum>maxi)maxi=sum;
        }
        return maxi;
    }
    int main()
    {
    	#if(FLAG)
          	  freopen("in.txt", "r", stdin);
    	//freopen("out.txt", "w", stdout);
    	#endif
    //******程序读入下一组据数之前先【初始化】变量,组数,器容等!!
        int T,i,j,n,m,maxi;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            maxi=0;
            for(i=0;i<n;i++)
            {
                for(j=0;j<m;j++)
                {
                    scanf("%d",&a[i][j]);
                }
            }
    
            for(j=0;j<m;j++)
                for(i=n-2;i>=0;i--)
                {
                    a[i][j]+=a[i+1][j];
                }
    
            for(i=0;i<n;i++)
            {
                int t=maxsum(a[i],m);
                if(maxi<t)maxi=t;
            }
    
    
            for(i=0;i<n;i++)
            {
                for(j=i+1;j<n;j++)
                {
                   for(int k=0;k<m;k++)
                    {
                        b[k]=a[i][k]-a[j][k];
                    }
                    int t=maxsum(b,m);
                    if(maxi<t)maxi=t;
                    /*
                    int sum=0;//这里也可以不调用函数,省了一次环循,用不算计b[k]了;
                    for(int k=0;k<m;k++)
                    {
                        if(sum<0)sum=a[i][k]-a[j][k];
                        else sum+=a[i][k]-a[j][k];
                        if(sum>maxi)maxi=sum;
                    }
                    */
                }
            }
            cout<<maxi<<endl;
        }
    	return 0;
    }

        如果应用其中注释的部份,省间时;

        至于二维转一维的理原,我还不甚明确,只是觉感是这么回事,如果有哪位大牛晓得敬请指点迷津。

        

        

        

    文章结束给大家分享下程序员的一些笑话语录: 一程序员告老还乡,想安度晚年,于是决定在书法上有所造诣。省略数字……,准备好文房4宝,挥起毛笔在白纸上郑重的写下:Hello World

  • 相关阅读:
    五、mariadb遇到的坑——Linux学习笔记
    四、CentOS 安装mariadb——Linux学习笔记
    [搬运] C# 这些年来受欢迎的特性
    [搬运] 写给 C# 开发人员的函数式编程
    [搬运]在C#使用.NET设计模式的新观点
    在容器中利用Nginx-proxy实现多域名的自动反向代理、免费SSL证书
    [翻译]在 .NET Core 中的并发编程
    [翻译] 使用ElasticSearch,Kibana,ASP.NET Core和Docker可视化数据
    .NET Core:使用ImageSharp跨平台处理图像
    .NET Core开源组件:后台任务利器之Hangfire
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3050599.html
Copyright © 2011-2022 走看看