DP动态规划——最大数字子串

来源:互联网 发布:js怎么遍历jsonobject 编辑:程序博客网 时间:2024/05/19 06:35

http://acm.nankai.edu.cn/p1760.html


最大数字子串


Time Limit: 1500 ms    Memory Limit:10000 kB  
Judge type: Multi-cases
Total Submit : 1215 (245 users)   Accepted Submit :397 (209 users)   Page View : 6115 

Font Style:AaAaAa

输入n(1<=n<=1e6)和n个整数,这n个整数的绝对值均小于1000,求最大数字子串之和。

Input

输入为多组样例数据,每组第一行为一个正整数n,第二行为n个整数组成的数字串。

Output

对于每组样例,输出仅为一行,表示最大数字子串的各项之和。

Sample Input

9

-3 4 9 2 -10 -7 11 3 -8

13

-1 2 6 -3 5 -7 14 -5 -15 1 8 -4 9

Sample Output

15

17

Hint

在第一组中,最大的数字子串是4 9 2的和
在第二组中,最大的数字子串是2 6 -3 5 -7 14的和


方法:

-3   4  9   2   -10  -7   11   3   -8

记录方法:

   -3  4   13  15  5     -7    11  14  6

   把当前的最大和(含当前末尾的最大和)记录下来,虽然不能直接得出最大和是多少,但可以进行遍历搜索最大值即可!

v     关键是要对负数处理好,看例二,最大子串含有负数。

-12 6 -3 5 -7 14 -5 -15 1 8 -4 9

-12 8

如果在此处断开记录-3,那么前面的26两个正数就和后边断开了,实际上2+6+-3>0,如果后边是正数的话,完全可以加上这3个数(比如后边的5

-12 8 5 10

相同处理: -1 2 8 5 10 317 12

后面是-15,加上12(前面的子串能形成的最大和)也小于0,所以此处应该断开了!记录-15

最后-1 2 8 5 10 3 1712 -15 1 8 4 13

 

 

v    输入数组a[i],用数组s[i]记录最后一个数为a[i]时的最大子串和

v    状态转移方程为  

v    s[i] = max(s[i-1]+a[i],a[i]); 1<=i<n-1  

v    初始条件s[0]=a[0]

v    然后s[i]中最大元素即为所求。 

 

AC代码:

 

#include<stdio.h>int a, s;int main(){int i,n,num;while(~scanf("%d",&n)){scanf("%d",&s);num=s;for(i=1;i<n;i++){scanf("%d",&a);if(s<0)s=a;elses+=a;if(num<s) num=s;}printf("%d\n",num);}return 0;}


 

 

TLE代码:


#include<stdio.h>int a[2000000],s[2000000];int main(){int i,n,num;   //num记录最大值while(~scanf("%d",&n)){for(i=0;i<n;i++)scanf("%d",&a[i]);num=s[0]=a[0];for(i=1;i<n;i++)if(s[i-1]<0)s[i]=a[i];elses[i]=s[i-1]+a[i];for(i=1;i<n;i++)if(num<s[i]) num=s[i];printf("%d\n",num);}return 0;}

原创粉丝点击