HDU-Java-1003

    

Max Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 276374    Accepted Submission(s): 65636


Problem Description
Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
 

Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
 

Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
 

Sample Input
 
  
2 5 6 -1 5 4 -7 7 0 6 -1 1 -6 7 -5
 

Sample Output
 
  
Case 1: 14 1 4 Case 2: 7 1 6
 求最大子串。由于此题很简单可以用别的办法,但是其实这是动态规划的题,为了训练效果我们还是选择用动态规划来做。
先贴上代码:
import java.util.Scanner;
public class pro1003 {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
      Scanner cin=new Scanner(System.in);
      while(cin.hasNext())
      {
      int T=cin.nextInt();
      
      int No=1;
      while(T>0)
      {
    	  
    	  int N=cin.nextInt();
    	  int[] num=new int[N]; 
    	  for(int i=0;i<N;i++)
    	  {
    		  num[i]=cin.nextInt();
    	  }
    	 int maxSum=-10000,thisSum=0;    //最大值先取小一点
    	 int start=0,end=0;    //起始和终止坐标
    	 for(int i=0;i<N;i++)
    	 {
    		 thisSum+=num[i];   		 
    		 if(thisSum>maxSum)
    			 {
    			     maxSum=thisSum;    //如果现在的这个串大,就赋值 
    			     end=i;//起始的位置比较难确定,但是我们至少可以确定终止的位置。如果这个if成立的话,终止的位置一定是i
    			 }
    		 if(thisSum<0)
    		 {
    			 thisSum=0;  	//一个最大子串的开头(一个或多个的和)不会是负值,除非这个最大子串自己就是负的,but别人都比他负的还多		                       //这题实际上还考虑了负值的情况,如果都是正值情况会简单一点。但其实也差不多,思考后调整一点点就可以
    		 }   		 
    	 }
    	 int sum=0;
    	 for(int i=end;i>-1;i--)
    	 {    		                       //再把起始位置通过遍历算出来即可
    		 sum+=num[i];
    		 if(sum==maxSum)start=i;
    	 }
    	 
    	 System.out.println("Case "+No+":"); 
    	 System.out.println(maxSum+" "+(start+1)+" "+(end+1));
    	 No++;
    	 if(T!=1)System.out.println();
    	 T--;
    	  
      }
	}
	}
}

在下也是初学算法,做了几道题了,写文章顺便也是自我总结。这是我记录动态规划的第一篇文章,下面说说我目前对于动态规划的理解。
书上都说动态规划就是从前一个状态用递推得到后面的状态,去各个地方看都是这种解释。当然,这完全没有问题。可是问题并不是这么简单的解释。或者说这样的解释省略了一些东西没有讲。

从之前的状态得到后面的状态,并不是写一个dp数组,然后从0开始for循环循环到n就得到你想要的结果那么回事。很多题目远比这来的复杂。比如说,很多情况下要比较。也就是说,可能是用多个之前的状态,从中经过某种方式的比较,比如说大小,或者处理之后再比较,总之经过一种比较的方式,得到目前的状态。而且,目前的状态,也未必就是那个答案。比如说一个dp[i][j],它也不一定就是问题在(i,j)时的答案。很多时候这只是一个可能的值。我保证的只是如果dp[i][j]满足我需求的答案的条件,那么它可能是这样的值。也就是说答案一定在所有的dp数组里面。然后可能需要再经过比较,得出最后答案。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值