POJ 1651 Multiplication Puzzle(区间dp)

本文详细解析了POJ 1651 Multiplication Puzzle问题的动态规划解决方案,通过定义子问题并利用递推公式,有效地解决了最小化得分的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接http://poj.org/problem?id=1651

                                                                                  Multiplication Puzzle
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 8569 Accepted: 5353

Description

The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one card out of the row and scores the number of points equal to the product of the number on the card taken and the numbers on the cards on the left and on the right of it. It is not allowed to take out the first and the last card in the row. After the final move, only two cards are left in the row.

The goal is to take cards in such order as to minimize the total number of scored points.

For example, if cards in the row contain numbers 10 1 50 20 5, player might take a card with 1, then 20 and 50, scoring
10*1*50 + 50*20*5 + 10*50*5 = 500+5000+2500 = 8000

If he would take the cards in the opposite order, i.e. 50, then 20, then 1, the score would be
1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150.

Input

The first line of the input contains the number of cards N (3 <= N <= 100). The second line contains N integers in the range from 1 to 100, separated by spaces.

Output

Output must contain a single integer - the minimal score.

Sample Input

6
10 1 50 50 20 5

Sample Output

3650

       递推式是 DP 的核心,得到递推式也就基本得到了 DP 的代码。DP 问题的特征是最优子结构,即问题包含多个子问题,问题的最优解中包含子问题的最优解。求解过程中相同的子问题可能多次被遇到,把已经求出答案的子问题的解记录到表中,这样问题的复杂度通常从指数降低到多项式。

 

    (1)规模最小的子问题最容易,是三个数字,结果是三个数字的乘积。

    (2)为了把问题分解成规模更小的子问题,定义问题如下,给出一个整数数组 c [ ],求索引从 i 到 j 范围的一串卡片操作到最后得到的最小结果是 s[i][j],问题规模是卡片数,即 j - i - 1;

    (3)类似矩阵乘法,现在把 s[i][j] 从中间某个位置(i < k < j)分裂成规模更小的两个子问题,即是把数字串的长度减小:

    c[i], ..., c[k], ..., c[j]; ( c[k] 是最后取走的牌 )

    先把 c[i] , ... , c[k] 中间的所有数字取走,根据问题定义得到结果是 s[i][k]; 剩下的是 c[i], c[k], ..., c[j];

    再把 c[k], ... , c[j] 中间的所有数字取走,根据问题定义得到结果是 s[k][j]; 剩下的是 c[i], c[k], c[j];

    最后取走 c[k];因此如果最后取走 k ,则 s[i][j] = s[i][k] + s[k][j] + c[i]*c[k]*c[j]; 

 

    因此这就是要找的递推式:(由于题目要求得到的结果最小,因此下面的式中取最小值)

 

    s[i][j] = min ( s[i][k] + s[k][j] + c[i]*c[k]*c[j] );  ( i < k < j )

 

    从上式可以看到,子问题的最优解是最终问题的最优解的一部分。 

    解法和矩阵乘法相同,都是从下至上求解(子问题规模从小到大),即先求解最小的问题,逐渐叠加上去,直到得到最终的规模问题的解。在此题中问题规模是数字串包含的数字个数,从 3 一直增加到卡片总数。在求解问题规模为 j - i + 1 的所有问题时,依赖更小规模的子问题,也就是说所有长度小于 j - i + 1的子问题都应该已求解完毕。从矩阵 s 来看,是从近对角线位置依次求解到矩阵右上角。


#include <iostream>
#include <string.h>
using namespace std;
int dp[105][105];
int main()
{
    int n, a[105];
    while(cin >> n){
        for(int i = 1; i <= n; i++){
             cin >> a[i];
             dp[i-1][i] = 0;
        }
       // memset(dp, 0, sizeof(dp));//这里其实是把dp[i][i+1]置为0,所以直接将其放到上面for循环里也可以
        for(int len = 2; len < n; len++)
            for(int i = 1; i < n - len + 1; i++){
                int j = i + len;
                dp[i][j] = 0x3f3f3f3f;
                for(int k = i + 1; k < j; k++)
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] +  a[i]*a[k]*a[j]);

            }
        cout << dp[1][n] << endl;
    }
    return 0;
}



内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值