[简单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。

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

你可能感兴趣的:(poj)