uvaoj384最优矩阵链乘(详解 + 思考 + 记忆化搜索 + 递推 )
来源:互联网 发布:足下软件学院校长 编辑:程序博客网 时间:2024/05/29 05:55
uvaoj384
本题一直让我WA的是 INF的设定,一定要大! 2^30 (1073741824)
输出格式要留心一些就可以啦,注意只输入一组答案是什么
比如:
1
5 1
输出是 (A1) 不是 A1
printf("Case %d: ",count++);if(n == 1){printf("(A1)\n");continue;} //单独输出dfs( 0 ,n);print(0 , n);printf("\n");
在给几组测试的数据
10
2 84
84 66
66 8
8 410
410 8
8 96
96 10
10 200
200 10
10 2
10
2 64
64 8
8 55
55 333
333 44
44 887
887 554
554 1
1 226
226 33
0
output
Case 1: (((A1 x A2) x A3) x (A4 x (A5 x (A6 x (A7 x (A8 x (A9 x A10)))))))
Case 2: ((A1 x (A2 x (A3 x (A4 x (A5 x (A6 x (A7 x A8))))))) x (A9 x A10))
记忆化搜索好想,注意好区间的控制就可以,要知道每一层的回退,都会得到一个区间内的链乘最小值,记录到
d[][]中,一定要理解d所存值的意义。
#include<stdio.h>#include<string.h>#define min(a,b) a<b?a:b#define INF 1073741824int d[20][20], a[20],vis[20][20] ,sum = 0; int dfs(int l ,int h){if(h-l==1)return 0;if(d[l][h]>0)return d[l][h];int k,ans;ans = INF;for(k = l+1;k<h;k++){if(ans > dfs(l,k) + dfs(k,h) + a[l]*a[k]*a[h]){ans = d[l][k] + d[k][h] + a[l]*a[k]*a[h]; //回退后的区间对应有最小值,已经存在d[][]了vis[l][h] = k;}}d[l][h]=ans;return ans; }void print(int l ,int h){ if(h-l==1){ printf("A%d",l+1);return;} int k = vis[l][h]; printf("("); print(l,k); printf(" x "); print(k,h); printf(")"); }int main(){int n,i,j,count =1;while(scanf("%d",&n)){ memset(d,0,sizeof(d));memset(vis,0,sizeof(vis));if(n==0)break;for(i = 0;i<n;i++){scanf("%d %d",&a[i],&a[i+1]);}printf("Case %d: ",count++);if(n == 1){printf("(A1)\n");continue;} //单独写出来dfs( 0 ,n);print(0 , n);printf("\n");}return 0;}
数组递推
最有意思的就是二维数组了,它可以表示任意连续区间 i到 j (i表示该区间开始的位置,j表示该区间结尾的位置。一共占整个二维数组空间的上三角位置。
前提,先理解 二维数组 在这里的意义。
递推思路:
1.通过区间的大小开始递推,从长度为1 的区间开始推(从小区间推大区间),然后推到n 。这时, d表示区间大小的变量决定一层循环
2.区间的递推 需要有开始的位置,这时,表示行的 i 就表示开始的位置(上三角),决定一层循环
3. i的位置,d的大小,决定了 j(区间结束的位置)
4. k的枚举分割了,了 i 到 j 的区间。 dp[i][j] = min( dp[i][j] , d[i][k] + d[k+1][j] + w(i,j,k)) (每层的分割都建立在上一层分割的基础上,而上一层的分割已经确定了最小链乘值。
理解之后,写递推就方便多了。
以单个矩阵为基础的区间划分 (左闭右闭)
#include<stdio.h>#define INF 1<<30int dp[20][20],path[20][20];void print(int l ,int h) { if(h == l){ printf("A%d",l+1);return;} //不知道大家注意到没,这里的条件变了,由于这是以每一个矩阵为基础去划分区间 int k = path[l][h]; //上个记忆化搜索是以 把矩阵的每个元素x,y打到了一位数组上了,那么就是以元素为基础去划分区间 printf("("); print(l,k); printf(" x "); print(k+1,h); //注意 printf(")");}int main(){int n,i,j,k,d,ans,count = 1;int left[20],right[20];while(scanf("%d",&n)){if(n ==0)break;for(i =0;i<n ;i++){scanf("%d %d",&left[i],&right[i]);}for(i = 0;i<=n;i++)dp[i][i] = 0;for(i =0;i<=n;i++)for(j =i+1;j<=n;j++) dp[i][j] = INF;for(d = 1;d<n ;d++)for( i =0;i+d <n;i++){j = i+d; //最少两个for( k =i;k<j;k++){if(dp[i][j]>dp[i][k] + dp[k+1][j] + left[i]*right[k]*right[j]){dp[i][j] = dp[i][k] + dp[k+1][j] + left[i]*right[k]*right[j];path[i][j] = k;}}} printf("Case %d: ",count++);if(n == 1){printf("(A1)\n");continue;}print(0 , n-1); //注意printf("\n");}return 0;}
在此,再给出 将元素打到一维数组上,以元素为基础的区间划分,输出函数又和写记忆化搜索是一样的了
(左闭右开)
#include<stdio.h>#include<string.h>#define INF 1<<30int dp[20][20],path[20][20];void print(int l ,int h){ if(h - l == 1){ printf("A%d",l+1);return;} int k = path[l][h]; printf("("); print(l,k); printf(" x "); print(k,h); //注意 printf(")"); }int main(){int n,i,j,k,d,ans,count = 1;int v[20];while(scanf("%d",&n)){if(n ==0)break;for(i =0;i<n ;i++){scanf("%d %d",&v[i],&v[i+1]);}memset(dp,0,sizeof(dp));for(d = 1;d<= n ;d++)for( i =0;i+d<=n;i++){j = i+d+1; //最少三个元素dp[i][j] = INF;for( k =i+1;k<j;k++){if(dp[i][j]>dp[i][k] + dp[k][j] + v[i]*v[k]*v[j]){dp[i][j] = dp[i][k] + dp[k][j] + v[i]*v[k]*v[j];path[i][j] = k;}}} printf("Case %d: ",count++);if(n == 1){printf("(A1)\n");continue;}print(0 , n); //注意printf("\n");}return 0;}
以上代码,全部AC了,大胆的看吧(*^__^*) 。
- uvaoj384最优矩阵链乘(详解 + 思考 + 记忆化搜索 + 递推 )
- 最优矩阵链乘 记忆化搜索
- [算法]最优矩阵链乘(动态规划 记忆化搜索)
- POJ 1179 Polygon 矩阵链乘 记忆化搜索
- 最优矩阵链乘
- 最优矩阵链乘
- 最优矩阵链乘
- 最优矩阵链乘
- 最优矩阵链乘
- 最优矩阵链乘
- 最优矩阵链乘(经典DP)
- dp经典矩阵连乘-记忆化搜索实现
- 最优矩阵链乘次序
- 9.1数字三角形(记忆化搜索与递推)
- 记忆化搜索与递推
- POJ 1179 Polygon(最优矩阵链乘)
- UVa 348 最优矩阵链乘 (DP)
- 动态规划 (二) 最优矩阵链乘
- 进程调度
- 喷水装置(一)t贪心算法
- 20160406servlet学习笔记验证码
- LeetCode 12 Integer to Roman
- NOJ-2076-天神小学-典型BFS题型
- uvaoj384最优矩阵链乘(详解 + 思考 + 记忆化搜索 + 递推 )
- Quick_触摸事件
- 如何将linux虚拟机和主机之间连接
- 如何去掉listview headview的 divider
- 【坑】使用拦截器跳转Action无法获取到传递过来的参数
- hdu4292Food(网络流裸题)
- 批量图片格式转化
- 点击 某个字段 ----------弹出div
- hadoop学习一