题目链接:1021
每次只能合并相连的石堆-.-我们可以建一个dp
dp [ i ] [ k ] 表示从i号一共K个石头合并再一起所花费的代价-.-
转换方程1:dp[ i ] [ k ]=min( dp [ i ] [ k ] ,dp[ i ] [ j ] +dp [i+k ] [ k-j] +he[ i ] [ k ]); j代表合并时第一个的长度--he[ i ] [ k ] 代表从i开始k个石头的代价和
转换方程1:dp[ i ] [ k ]=min( dp [ i ] [ k ] ,dp[ i ] [ j-i ] +dp [ j ] [ k-j+i] +he[ i ] [ k ] ); j代表合并时后一个的开头--he[ i ] [ k ] 代表从i开始k个石头的代价和
代码1:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[120][120],he[120][120],shu[120];
int main()
{
int n;scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
dp[i][j]=999999999;
memset(he,0,sizeof(he));
for (int i=1;i<=n;i++)
{
scanf("%d",&shu[i]);
dp[i][1]=0;
}
for (int k=2;k<=n;k++)
for (int i=1;i+k-1<=n;i++)
for (int j=i;j<i+k;j++)
he[i][k]+=shu[j];
for (int k=2;k<=n;k++)
for (int i=1;i+k-1<=n;i++)
for (int j=1;j<k;j++)
dp[i][k]=min(dp[i][k],(dp[i][j]+dp[i+j][k-j])+he[i][k]);
printf("%d\n",dp[1][n]);
return 0;
}
代码2:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[120][120],he[120][120],shu[120];
int main()
{
int n;scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
dp[i][j]=999999999;
memset(he,0,sizeof(he));
for (int i=1;i<=n;i++)
{
scanf("%d",&shu[i]);
dp[i][1]=0;
}
for (int k=2;k<=n;k++)
for (int i=1;i+k-1<=n;i++)
for (int j=i;j<i+k;j++)
he[i][k]+=shu[j];
for (int k=2;k<=n;k++)
for (int i=1;i+k-1<=n;i++)
for (int j=i+1;j<i+k;j++)
dp[i][k]=min(dp[i][k],(dp[i][j-i]+dp[j][k-j+i])+he[i][k]);
printf("%d\n",dp[1][n]);
return 0;
}