环形沙子合并

环形沙子合并问题
问题描述:设有N堆沙子排成一圈,其编号为1,2,3,…,N(N<=300)。每堆沙子有一定的数量,可以用一个整数来描述,现在要将这N堆沙子合并成为一堆,每次只能合并相邻的两堆,合并的代价为这两堆沙子的数量之和,合并后与这两堆沙子相邻的沙子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同,如有4堆沙子分别为 1  3  5  2 我们可以先合并1、2堆,代价为4,得到4 5 2 又合并 1,2堆,代价为9,得到9 2 ,再合并得到11,总代价为4+9+11=24,如果第二步是先合并2,3堆,则代价为7,得到4 7,最后一次合并代价为11,总代价为4+7+11=22;问题是:找出一种合理的方法,使总的代价最小。输出最小代价。
输入:
第一行一个数N表示沙子的堆数N。
第二行N个数,表示每堆沙子的质量。
输出:
合并的最小代价
样例:
输入:
4
1 3 5 2
输出:
20

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 
 8 int n,ans;
 9 int sum[605],zhui[303];
10 int f[305][305];
11 
12 int main() {
13     scanf("%d",&n);
14     ans=2000000000;
15     for(int x=1;x<=n;x++){scanf("%d",sum+x);sum[n+x]=sum[x];}  
16       for(int x=1;x<=n*2;x++)zhui[x]=zhui[x-1]+sum[x];
17     for(int x=2;x<=n;x++){
18           for(int y=1;y<=n;y++){
19               int r=x+y-1;
20             int he=zhui[r]-zhui[y-1];    
21               for(int z=1;z<x;z++){r=y+z;if(y+z>n)r=(y+z)%n;if(f[y][x]==0)f[y][x]=f[y][z]+f[r][x-z];else f[y][x]=min(f[y][z]+f[r][x-z],f[y][x]);}
22               f[y][x]+=he;
23             if(x==n)ans=min(ans,f[y][x]);
24           }    
25     }
26   printf("%d", ans);
27   return 0;
28 }
原文地址:https://www.cnblogs.com/Ateisti/p/5775191.html