给定整数m,n和数组x[n],找出某个i,使得x[i]+x[i+1]+x[i+2]+x[i+3]+x[i+4]…x[i+m]最接近于零。
(0<=i<n-m)
一.暴力解法
遍历各个i值,计算子序列的和,然后求出最接近0的
int find(int a[],int n,int m) //寻找m+1个数字,使得他们的和最小 { int i=0; int thissum=0; int j=0; int ans=INT_MAX; for(i=0;i<n-m;i++) //时间复杂度为O(m*n) { thissum=0; for(j=i;j<=i+m;j++) thissum+=a[j]; if(abs((int)(thissum))<abs((int)(ans))) ans=abs((int)thissum); } return ans; }
二.动态规划:
建立数组dp[],dp[i]存放的是x[i]+x[i+1]+…x[i+m]的值,则递推关系式为:
dp[i+1]=dp[i]-a[i]+a[i+1+m],然后遍历dp[]数组,求出最近于零的。
int find2(int a[],int n,int m) { int *dp=(int *)malloc(n*sizeof(int)); int i=0; int tmp=0; for(i=0;i<=m;i++) { tmp+=a[i]; } dp[0]=tmp; for(i=1;i<n-m;i++) { dp[i]=dp[i-1]+a[i+m]-a[i-1]; } int ans=INT_MAX; for(i=0;i<n;i++) { if(abs((int)dp[i])<ans) ans=abs((int)dp[i]); } return ans; }时间复杂度为O(n),空间复杂度为O(n)
还可以对上面的代码稍作改进,上面的dp[]数组,只要用一个变量即可。
int find3(int a[],int n,int m) { int tmp=0; int ans=INT_MAX; int i=0; for(i=0;i<=m;i++) tmp+=a[i]; if(abs((int)tmp)<ans) ans=abs((int)tmp); for(i=1;i<n-m;i++) { tmp=tmp-a[i-1]+a[i+m]; if(abs((int)tmp)<ans) ans=abs((int)tmp); } return ans; }
时间复杂度为O(n),空间复杂度为O(1)
完整代码为:
# include <iostream> # include <cstdlib> # include <cmath> # include <ctype.h> using namespace std; int find(int a[],int n,int m) //寻找m+1个数字,使得他们的和最小 { int i=0; int thissum=0; int j=0; int ans=INT_MAX; for(i=0;i<n-m;i++) //时间复杂度为O(m*n) { thissum=0; for(j=i;j<=i+m;j++) thissum+=a[j]; if(abs((int)(thissum))<abs((int)(ans))) ans=abs((int)thissum); } return ans; } int find2(int a[],int n,int m) { int *dp=(int *)malloc(n*sizeof(int)); int i=0; int tmp=0; for(i=0;i<=m;i++) { tmp+=a[i]; } dp[0]=tmp; for(i=1;i<n-m;i++) { dp[i]=dp[i-1]+a[i+m]-a[i-1]; } int ans=INT_MAX; for(i=0;i<n;i++) { if(abs((int)dp[i])<ans) ans=abs((int)dp[i]); } return ans; } int find3(int a[],int n,int m) // { int tmp=0; int ans=INT_MAX; int i=0; for(i=0;i<=m;i++) tmp+=a[i]; if(abs((int)tmp)<ans) ans=abs((int)tmp); for(i=1;i<n-m;i++) { tmp=tmp-a[i-1]+a[i+m]; if(abs((int)tmp)<ans) ans=abs((int)tmp); } return ans; } int main() { int a[10]={1,-2,3,-4,-5,-6,7,8,9,0}; cout<<find(a,10,3)<<endl; cout<<find2(a,10,3)<<endl; cout<<find3(a,10,3)<<endl; system("pause"); return 0; }
原文:http://blog.csdn.net/u011608357/article/details/38143105