Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4363 | Accepted: 2569 |
Description
Input
Output
Sample Input
6 10 1 50 50 20 5
Sample Output
3650
输入一串数字,然后除了第一个和最后一个之外,其他的数字,每次可以移走一个,然后和它的左右两个数字做相乘,最后只剩下2个数字,就是第一个和最后一个。然后要求出刚刚算出的那些积的和的最小值。从题目中给的例子就可以看出来其实这道题目和矩阵连乘是一样的,把它的n个输入转化为是n-1个矩阵的行数和列数,那就和矩阵连乘问题一样了。
矩阵连乘问题,一个很经典的DP问题。
用DP解这道题的时候,需要找到递归方程,也就是下面这条
其中m[i][j]代表的是矩阵Mi....Mj之间的乘法的最小次数.根据这个来写代码,就清晰多了。
我觉得这个题目还需要注意的是输入数据只有一个。
代码如下:
#include<iostream> #include<stdio.h> using namespace std; int weight[100+10][100+10];//储存1....n相乘需要的次数 int p[100+10];//储存每个矩阵的列数 void init(int n) {//初始化 for(int i=0;i<=n;i++) { cin>>p[i]; } } void matrixchain(int n) {//计算weight值 for(int i=0;i<=n;i++) { weight[i][i]=0; } for(int r=1;r<=n;r++) { for(int i=1;i<=n-r;i++) { int j=i+r; weight[i][j]=weight[i][j-1]+p[i-1]*p[j-1]*p[j];//假如从j-1个矩阵分开
for(int k=i;k<j;k++) { int t=weight[i][k]+weight[k+1][j]+p[i-1]*p[k]*p[j];//假如从第k个矩阵分开 if(t<weight[i][j]) { weight[i][j]=t; } } } } } int main() { int n; cin>>n; n--; init(n); matrixchain(n); cout<<weight[1][n]<<endl; return 0; }