DP/四边形不等式
裸题环形石子合并……
拆环为链即可
1 //HDOJ 3506 2 #include<cmath> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define rep(i,n) for(int i=0;i<n;++i) 10 #define F(i,j,n) for(int i=j;i<=n;++i) 11 #define D(i,j,n) for(int i=j;i>=n;--i) 12 #define pb push_back 13 #define CC(a,b) memset(a,b,sizeof(a)) 14 using namespace std; 15 int getint(){ 16 int v=0,sign=1; char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();} 18 while(isdigit(ch)) {v=v*10+ch-'0'; ch=getchar();} 19 return v*sign; 20 } 21 const int N=2010; 22 const int INF=1000000000; 23 const double eps=1e-8; 24 /*******************template********************/ 25 int s[N][N],a[N]; 26 int dp[N][N]; 27 int main(){ 28 #ifndef ONLINE_JUDGE 29 freopen("input.txt","r",stdin); 30 // freopen("output.txt","w",stdout); 31 #endif 32 int n; 33 while(scanf("%d",&n)!=EOF && n){ 34 CC(a,0);CC(s,0); 35 F(i,1,n) a[i+n]=a[i]=getint(); 36 F(i,1,n<<1) a[i]+=a[i-1]; 37 F(i,1,n*2-1){ 38 dp[i][i+1]=a[i+1]-a[i-1]; 39 s[i][i+1]=i; 40 } 41 F(len,3,n) 42 F(i,1,n*2-len+1){ 43 int j=i+len-1; 44 dp[i][j]=INF; 45 F(k,s[i][j-1],s[i+1][j]){ 46 int tmp=dp[i][k]+dp[k+1][j]+a[j]-a[i-1]; 47 if (tmp<dp[i][j]){ 48 dp[i][j]=tmp; 49 s[i][j]=k; 50 } 51 } 52 } 53 int ans=INF; 54 F(i,1,n) ans=min(ans,dp[i][i+n-1]); 55 printf("%d ",ans); 56 } 57 return 0; 58 }