Sequence
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
Given an integer number sequence A of length N (1<=N<=1000), we define f(i,j)=(A[i]+A[i+1]+...+A[j])^2 (i<=j). Now you can split the sequence into exactly M (1<=M<= N) succesive parts, and the cost of a part from A[i] to A[j] is f(i,j). The totle cost is the sum of the cost of each part. Please split the sequence with the minimal cost.
输入
At the first of the input comes an integer t indicates the number of cases to follow. Every case starts with a line containing N ans M. The following N lines are A[1], A[2]...A[N], respectively. 0<=A[i]<=100 for every 1<=i<=N.
输出
For each testcase, output one line containing an integer number denoting the
minimal cost of splitting the sequence into exactly M succesive parts.
示例输入
1 5 2 1 3 2 4 5
示例输出
117
提示
来源
山东省第二届ACM大学生程序设计竞赛
示例程序
(动态规划)不过对时间要求很高,考试时用几种方法都是超时,之后看到了比较有技巧的思路,
1 #include <iostream> 2 #include <stdio.h> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <stdlib.h> 7 8 using namespace std; 9 typedef long long ll; 10 ll sum[1010]; 11 ll ans[1010]; 12 ll min (ll a,ll b) 13 { 14 return a<b?a:b; 15 } 16 int main() 17 { 18 int T; 19 scanf("%d",&T); 20 while(T--) 21 { 22 int n,m; 23 scanf("%d %d",&n,&m); 24 ll t; 25 int arr; 26 sum[0]=0; 27 for(int i=1;i<=n;i++) 28 { 29 scanf("%d",&arr); 30 sum[i]=sum[i-1]+arr; 31 ans[i]=sum[i]*sum[i]; 32 33 } 34 for(int i=2;i<=m;i++)//刷新数组次数 35 { 36 for(int j=n-m+i;j>=i;j--)//倒叙刷新 37 { 38 for(int k=i-1;k<j;k++) 39 { 40 t=sum[j]-sum[k]; 41 ans[j]=min(ans[k]+t*t,ans[j]); 42 } 43 } 44 } 45 //printf("%I64d\n",ans[n]); 46 cout<<ans[n]<<endl; 47 } 48 return 0; 49 }
最大的收获就是在linux系统中%I64d表示longlong类型可能会出错,就是因为这个,提交了好几遍PE.