算法提高 矩阵乘法

来源:互联网 发布:中国历届人口普查数据 编辑:程序博客网 时间:2024/06/05 08:27
这道题当初做的时候完全没思路,对DP也是完全搞不懂。现在抽时间复习了一下,看着DP函数部分还是一脸懵逼,上网找了找答案,可是要么讲的很复杂,要么直接给代码,给我造成了特别大的困扰。所以自己把测试用例带入,跟着编译器走了一遍,豁然开朗,原来是这么回事
下面是测试部分:
0 2 1  dp[1[2]=50
1 3 2  dp[2][3]=1000
0 3 1  dp[1][3]=1200 
0 3 2  dp[1][3]=150
看见这个瞬间就明白了,适用二维的dp[i][j]数组i代表起始位置a0,j代表末位置an知道dp数组的含义,动规就简单了。当初迷迷糊糊的不知道dp的意思,导致对这个题根本就理解的不了。分析测试部分的两个dp[1][3]应该就可以知道k在段代码中的作用的。
注意:代码中的数据类型需要自己改一下,这里是重新写了这个题目,重新理解一下动规,所以对数据类型就只用了int。题目中所要求的数据比较大。所以数据类型的选择很重要。代码中定义的宏变量INF需要15个9才能通过所有测试用例(因为这个错误,当初提交代码提交了好几次)。
动规中,如果是和max函数相关,dp初始化为一个0就可以,如果是min函数,特别小心dp初始化的值,尽量设置大一点(当然不能让编译器报错)这对蓝桥这种坑题有好处。
学习中不能理解的代码,耐着性子,调试几遍,会有意想不到的收获的。

才知道自己能力有多弱了,知识空白点太多了还要不断的学习学习啊。推荐这个博客http://blog.csdn.net/f_zyj?viewmode=contents她对题目的讲解特别详细。一看就会。
#include<stdio.h>#define INF 9999999999int dp[1005][1005];//i代表起始点,j代表末尾点 int num[10005];//矩阵元素int min(int a,int b){return a>b?b:a;} int DP(int n){int i,j,k;for(j=2;j<=n;j++){for(i=j-1;i>0;i--){dp[i][i]=dp[j][j]=0;//自己到自己的运算次数为零 for(k=i;k<j;k++){dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+num[i-1]*num[k]*num[j]);}}}return dp[1][n];//返回起始点和终点的dp }int main(void){int n;//矩阵个数int i,j;int temp;scanf("%d",&n);for(i=0;i<=n;i++){scanf("%d",&num[i]);//矩阵元素的输入 }if(n==1){printf("%d\n",num[0]*num[1]);return 0;}for(i=0;i<=n;i++){for(j=0;j<=n;j++){dp[i][j]=dp[j][i]=INF;//这里是一个无限大的值,因为是求min }}temp=DP(n);printf("%d\n",temp);return 0;}


0 0