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

 

posted @ 2016-09-14 16:06  Hadilo  阅读(352)  评论(0编辑  收藏  举报