poj1651:
题的大意是:给出一组N个数,每次从中抽出一个数(第一和最后一个不能抽)
,该次的得分即为抽出的数与相邻两个数的乘积。直到只剩下首尾两个数为止。问最小得分是多少?
这是一个矩阵连乘的稍稍变形:
Input
The first line of the input contains the number of cards N (3 <= N <= 100). The second line contains N integers in the range from 1 to 100, separated by spaces.
Output
Output must contain a single integer – the minimal score.
Sample Input
6 10 1 50 50 20 5
Sample Output
3650
一个经典题目:
#include <iostream>
#define NUM 105
using namespace std;
int main()
{
int D[NUM];
int N;
cin>>N;
int dp[NUM][NUM];
N--;
for(int i = 0;i<=N;i++)
cin>>D[i];
// for(int i = 1;i<=N+1;i++)
// cout <<D[i]<<" ";
// cout <<endl;
for(int i = 0;i<=N+1;i++)
dp[i][i] = 0;//如果是只有一个矩阵,连乘就是一个0;
//子问题的规模r = 1的时候;
for(int r = 2;r<=N;r++){//r为当前计算的链长;(子问题的规模)
for(int i =1 ;i<=N-r+1;i++){//n-r+1为最后一个r链长的前边界;
int j = i+r-1;//计算前边界为i长为r链的后边界;
//初始化dp[i][j];也就是划分为Ai(Ai+1..Aj)
dp[i][j] = dp[i+1][j]+D[i-1]*D[i]*D[j];
for(int k = i+1;k<=j-1;k++){
dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+D[i-1]*D[k]*D[j]);//划分为其他的时候;并且用最好的值替换;
}
}
}
// for(int i = 0;i<=N;i++){
// for(int j = 0;j<=N;j++)
// cout <<dp[i][j]<<" ";
// cout <<endl;
// }//测试dp;
cout<<dp[1][N]<<endl;
return 0;
}