最大整数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

原文地址:https://www.cnblogs.com/xinyuyuanm/p/3050599.html