加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 1651 动态规划

(2010-04-01 22:08:00)
标签:

poj

pku

1651杂谈

分类: 动态规划

    题目描述:依次从左到右给你n个数字,每次取出一个数字(这个数字不能是最两边的数字),这个数字和它左右两边的数字(一共三个数字)相乘,累加这个数。直到最后仅剩下两个数字。求最后累加的最小值。

    分析:dp。 dp[i][j]表示把第i个数字到第j个数字之间(不包括i,j)的数字去光后得到的最小值。

    设x[i]是第i个数字的值。

    dp[i][j] = min(dp[i][k] dp[k][j] x[i] * x[k] * x[j]),i 1 <= k <= j - 1

    所有连续的两个数已经符合要求,即dp[i][i 1] = 0;

    代码:

#include<iostream>
using namespace std;
int n, x[100], dp[100][100];
int dg(int a, int b)
{
    if (dp[a][b] != -1)
        return dp[a][b];
    if (b - a == 1)
        return dp[a][b] = 0;
    int min = 1000000000;
    for(int i = a 1; i <= b - 1; i )
    {
        int l = dg(a, i), r = dg(i, b);
        if (l r x[i] * x[a] * x[b] < min)
            min = l r x[i] * x[a] * x[b];
    }
    return dp[a][b] = min;
}
int main()
{
    scanf("%d", &n);
    memset(dp, -1, sizeof(dp));
    int min = 1000, id, pos, sum = 0;
    for(int i = 0; i < n; i )
        scanf("%d", &x[i]);
    printf("%d\n", dg(0, n - 1));
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有