题目链接:poj1738
本文转自:http://blog.csdn.net/u011328276/article/details/9669531
题意: 石子合并问题, 将相邻两堆石子合并, 每次得分是合并成新的一堆石子个数, 最后累加最小值.
解题思路:
这类题目可以参考:hdu3506 我的博客
可以参考一下博客,里面有一些每步是如何变化的:石子合并的GarsiaWachs算法
#include<iostream>
#include<iostream>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<cstdio>
using namespace std;
#define maxn 55555
int a[maxn],n,num,result;
void combine(int k)
{
int i,j;
int temp=a[k-1]+a[k];//a[k-1]和a[k]合并为一个 所以后面的往前一位
result+=temp;
for(int i =k;i<num-1;i++)
{
a[i]=a[i+1];
}
num--;
for(j=k-1;j>0&&a[j-1]<temp;j--)//往前查找一个a[j-1]比tmp大的 然后将tmp放在a[j]的位置
{
a[j]=a[j-1];
}
a[j]=temp;
while(j>=2&&a[j-2]<=a[j])//判断是否需要继续合并
{
int d=num-j;//因为这个三者中 合并前两个 所有对后面的个数没有影响
combine(j-1);
j=num-d;
}
}
int main()
{
while(~scanf("%d",&n))
{
if(n==0)break;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
num=1;
result=0;
for(int i=1;i<n;i++)
{
a[num++]=a[i];
while(num>=3&&a[num-3]<=a[num-1])//如果数组中至少存在3个数时候 开始进行合并
combine(num-2);
}
while(num>1)//这里情况是 a数组中个数均是由大到小合并 所以三者都是挑后两者先合并
combine(num-1);
printf("%d\n",result);
}
return 0;
}