圆环取数

来源:互联网 发布:时代周刊封面 知乎ps 编辑:程序博客网 时间:2024/06/09 08:20

每次任意去除相邻两个数,去掉较小的那个,并把它们差的绝对值加起来,重复这一过程,直到剩最后一个数为止。

f[i][j]代表i开始到j的最优解,max[i][j]表示i开始到j的最大值。

#include<cstdio>#include<cstring>#include<string.h>#include<algorithm>#include<iostream>#include<math.h>#include<vector>using namespace std;const long maxn=210;long n;long a[maxn];long f[maxn][maxn],maxx[maxn][maxn],f1;void process(){long i,j,k,len,tmp1,tmp2,tmp3,ans=-1;for(len=0;len<n;len++){for(int i=0;i<n;i++){j=i+len;if(len==0){f[i][j]=0;maxx[i][j]=a[i];continue;}f[i][j%n]=-1;for(k=i;k<j;k++){f1=f[i][k%n]+f[(k+1)%n][j%n];tmp1=maxx[i][k%n];tmp2=maxx[(k+1)%n][j%n];if(tmp1<tmp2)tmp3=tmp1,tmp1=tmp2,tmp2=tmp3;f1+=tmp1-tmp2;if(f1<f[i][j%n]||f[i][j%n]==-1)f[i][j%n]=f1;maxx[i][j%n]=tmp1;}if(len==n-1){if(ans==-1||f[i][j%n]<ans)ans=f[i][j%n];}}}printf("%ld\n",ans);}int main(){scanf("%ld",&n);long i;for(i=0;i<n;i++)scanf("%d",&a[i]);process();return 0;}