[ CodeVS冲杯之路 ] P1154
不充钱,你怎么AC?
题目:http://codevs.cn/problem/1154/
由于所有珠子连成一个环,所以要进行预处理,直接将整个值往后复制 n 位,即 a[i+n]=a[i]
设 f[i][j] 为区间 [i,j] 中的最大能量,显然,当复制完后从 2~n-1 能够涵盖所有的情况
这里特别要注意边界,我们发现 f[1][k] 和 f[k][2*n] (k=1~2*n) 是没有意义的,因为在此情况下不存在 a[0] 和 a[n*2+1],这种情况已经变到了 f[n+1][k] 与 f[k][n] 中 (k=1~2*n)
还要注意的一点是方程变量的边界条件(被坑了5次才A掉 T.T)
初始状态:f[i][i]=a[i]*a[i+1]*a[i-1] i=2~2*n-1
目标状态:max(f[i][j])
对于 i>j 的情况,此时 f[i][j]=0,并不会影响状态
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #define N 201 8 using namespace std; 9 10 int a[N],f[N][N],n,ans; 11 int main() 12 { 13 int i,j,k; 14 scanf("%d",&n); 15 for (i=1;i<=n;i++) 16 { 17 scanf("%d",&a[i]); 18 a[i+n]=a[i]; 19 } 20 n*=2; 21 for (i=2;i<n;i++) f[i][i]=a[i]*a[i-1]*a[i+1]; 22 for (k=1;k<n/2-1;k++) 23 { 24 for (i=2;i<n-k;i++) 25 { 26 for (j=i;j<=i+k;j++) 27 { 28 ans=max(f[i][i+k]=max(f[i][i+k],f[i][j-1]+f[j+1][i+k]+a[i+k+1]*a[i-1]*a[j]),ans); 29 } 30 } 31 } 32 printf("%d\n",ans); 33 return 0; 34 }