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;
}

 

原文地址:https://www.cnblogs.com/HpuAcmer/p/2456525.html