在一个操场上摆放着一排N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。
试设计一个算法,计算出将N堆石子合并成一堆的最小得分。
标签:
共一个数,即N堆石子合并成一堆的最小得分。
对于 100% 的数据,1≤N≤40000
对于 100% 的数据,1≤A≤200
个人认为还是比较简单的(在知道了GarsiaWachs算法后)
我只知道结论,设一个序列是A[0..n-1],每次寻找最小的一个满足A[k-1]<=A[k+1]的k,(方便起见设A[-1]和A[n]等于正无穷大)
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int Max=2000000000;
int n,i,j,k,m,ans,a[40005];
int main()
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
a[0]=Max;
a[n+1]=Max;
m=n;
for(i=1;i<n;i++)
{
k=0;
for(j=1;j<=m;j++)
if(a[j-1]<=a[j+1])
{
k=j;
break;
}
a[k-1]+=a[k];
for(j=k;j<m;j++)
a[j]=a[j+1];
k--;
ans+=a[k];
while(k>0&&a[k-1]<=a[k])
{
swap(a[k-1],a[k]);
k--;
}
a[m]=Max;
m--;
}
cout<<ans;
return 0;
}
标签:
原文地址:http://www.cnblogs.com/lwq12138/p/5425465.html