Multiplication Puzzle
题目链接:
http://poj.org/problem?id=1651
题意:
给出n个数字,从中取出n-2个,每取出一个,分数就会加上该数字和相邻两个数字的乘积(不能取左右两端的数字),求分数和最小值。
题解:
设dp[i][j]为区间[i,j]内取出j-i-1个数字的最小分数和,可以知道此时 i 和 j 为区间的左右端点,那么dp[i][j]的值就是在(i,j)内选一k值使得dp[i][k]+dp[k][j]+a[i]*a[k]*a[j]最小,这个最小值就是dp[i][j]的最终值,终点状态为dp[1][n]
代码
#include<stdio.h>
#include<string.h>
const int N=101;
int dp[N][N],a[N];
int mmin(int x,int y)
{
return x<y?x:y;
}
void solve()
{
int n;
while(~scanf("%d",&n))
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int len=2;len<n;++len)
{
for(int i=1;i+len<=n;++i)
{
int j=len+i;
for(int k=i+1;k<j;++k)
{
if(a[i]*a[k]*a[j]+dp[i][k]+dp[k][j]<dp[i][j]||!dp[i][j])
dp[i][j]=a[i]*a[k]*a[j]+dp[i][k]+dp[k][j];
}
}
}
printf("%d
",dp[1][n]);
}
}
int main()
{
solve();
return 0;
}