[简单DP] POJ 1651 Multiplication Puzzle

一看就知道是矩阵链,但是忘了矩阵链具体是怎么做的了,记的是把区间划分开来DP。

定义f[i, j]为 i-j 内的最小值(初始是1-n),如果第 k 个为最后选的数,那么 f[i, j] = f[i, k]+f[k,j]+a[i]*a[k]*a[j];

需要注意的是边界条件:如果区间内不含选取的数(i+1==j)最小值应该定义为0。

 1 /*
 2     POJ 1651 Multiplication Puzzle
 3 */
 4 
 5 # include <cstdio>
 6 # include <cstring>
 7 
 8 # define N 100 + 5
 9 # define INF 0x7FFFFFFF
10 
11 int n;
12 int a[N];
13 int f[N][N];
14 
15 int min(int x, int y)
16 {
17     return x<y ? x:y;
18 }
19 
20 int dp(int l, int r)
21 {
22     int &ans = f[l][r];
23     if (ans != -1) return ans;
24     if (l+1 == r) return ans = 0;
25     ans = INF;
26     for (int k = l+1; k < r; ++k)
27         ans = min(ans, dp(l, k)+dp(k,r)+a[k]*a[l]*a[r]);
28     return ans;
29 }
30 
31 void solve(void)
32 {
33     for (int i = 1;i <= n; ++i)
34     {
35         scanf("%d", &a[i]);
36         memset(f[i]+1, -1, sizeof(int)*n);
37     }
38     int ans = dp(1, n);
39     printf("%d\n", ans);
40 }
41 
42 int main()
43 {
44     while (~scanf("%d", &n))
45         solve();
46     
47     return 0;
48 }

不知道算不算区间DP,就归为简单DP。

不知道怎么打印出字典序最小的路径(能不能每次选取满足乘积最小的下标最大的数?)。

原文地址:https://www.cnblogs.com/JMDWQ/p/2621126.html