您的位置:首页 > 其它

算法提高 矩阵乘法

2017-04-05 23:32 330 查看


这道题当初做的时候完全没思路,对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 9999999999
int 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]
;//返回起始点和终点的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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  蓝桥杯