HDOJ 4223 (DP)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4223
题意很简单:n个数,找出连续m个数的最小绝对值。
先来个暴搜(N<=1000)
250MS
代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 1001
int a[N];
int main()
{
   int T,n,i,j,min,cnt;
   scanf("%d",&T);
   cnt = 1;
   
     do
     {
        scanf("%d",&n);
        
        scanf("%d",&a[0]);
        for(i = 1 ; i < n ; ++i)          
        {
           scanf("%d",&a[i]);
           a[i] += a[i-1];      
        }          
      
        min = 100000000;
        
        for(i = 0 ; i < n ; ++i)
        if(fabs(a[i]) < min)
        min = fabs(a[i]);
        
        for(i = 0 ; i < n ; ++i)
        for(j = i + 1 ; j < n ; ++j)
        if(fabs(a[j] - a[i]) < min)
          min = fabs(a[j] - a[i]);
        printf("Case %d: %d\n",cnt++,min);
     
     }while(--T); 
    
   //system("pause");
   return 0;    
}
可以改进,改进思路:一个数组(第0个位置放一个多余的0),每个数组元素都存放的是前面所有数的和,然后把这些和从小到达排序。每两个相邻数做差必可得最小值。为什么?因为相邻,所以存在最小;再看连续,因为一个数表示0~i之间的数的和,另一个表示0~j之间的数的和。相减即可得(i+1)~j或者(j+1)~i之间的和。
因此最小和连续都可以得到保证,所以算法正确。
改进代码(15MS):
#include <cstdio>
#include <algorithm>
#define N 1001
using namespace std;
int a[N];
int main()
{
    int n,i,T,tmp,min,cnt = 1;
	scanf("%d",&T);
	  do
	  {
		  scanf("%d",&n);
		  a[0] = 0;
		  for(i = 1 ; i <= n; ++i)
		  {
		    scanf("%d",&a[i]);
			a[i] += a[i-1];
		  }
           
	         sort(a,a+n+1);
		  
                min =10000000;
		  for(i = 1 ; i <= n;  ++i)
		  {
			  tmp = a[i] - a[i-1];
		         if(tmp < min) 
			  {
				  min = tmp;
			      if(!min) break;   
			  }
		  }
          printf("Case %d: %d\n",cnt++,min);
	  }while(--T);
     return 0;
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号