合并石子,每次选择相邻两堆,代价为两堆石子和,问最小代价
思路:其实就是分治,设左端点为l,右端点为r,中间任取一点k,则区间l~r可看作是l~k+k+1~r,所以就可以用分治的思想,直接上代码
memset(f,0x3f,sizeof(f));
for(int i=1;i<=n;i++)
f[i][i]=0;//初始化(合并它本身就是不用操作,当然是0)
for(int len=2;len<=n;len++)//len就是区间长度
for(int l=1,r=len;r<=n;l++,r++)//第一个区间当然是从1开始
for(int k=1;k<r;k++)中间的k点
f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]+sum[l~r]);//sum[l~r]就是一个为了能看懂的形式,并不能这么写。因为你要合并这两个区间,所以要加上它们的和
升级版:第一个石子和最后一个石子连起来,求最小代价
思路:合并n堆石子,只要n-1条边就行了,但是现在有n条边,所以就相当于有一条边不用,设石子是a1,a2,a3...an,在后边再接一列一样的。也就是变成a1,a2,a3...an,a1,a2...an这样的话,就可以一个个假设不用哪条边比如说不用a1,a2相连的这条边,那么就是求f[2][n+1],如果是a2,a3,那么就是求f[3][n+2].....这样就可以转化为第一个问题了