Multiplication Puzzle(区间DP:类似矩阵连乘问题的DP模板)
来源:互联网 发布:hash算法特点 编辑:程序博客网 时间:2024/05/21 06:01
Link:http://poj.org/problem?id=1651
Multiplication Puzzle
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 7424 Accepted: 4596
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.
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
If he would take the cards in the opposite order, i.e. 50, then 20, then 1, the score would be
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
610 1 50 50 20 5
Sample Output
3650
Source
Northeastern Europe 2001, Far-Eastern Subregion
题意:给出一组数,每删除一个数的代价是其左右两边的数与之连乘的数值,求除了首尾两个数之外,删除中间所有数的最小代价是多少。
编程思想:区间DP。详见下面代码注释。
AC code:
#include<iostream>#include<algorithm>#include<stdio.h>#include<cstring>#include<cmath>#include<vector>#include<string.h>using namespace std;const int INF=0x3f3f3f3f;int dp[111][111];int card[111];/*dp[i][j]表示删除区间i+1至j-1的最小代价,其中j>=i+2,所以转态转移方程为:dp[i][j]=min(card[i]*card[k]*card[j]+dp[k][j]+dp[i][k]),k=i+2~j-2;k是最后一个删除的位置注意初始化问题:这里k不从i+1开始和j-1结束的原因是这两个点必须作为初始化用,不然递推式中dp[k][j]和dp[i][k]的值一开始没初始化,不知道其值是多少,无法进行递推而这里初始化方式类似类似递归时二分的那种分治思想,初始化dp[i][k]相当于求左边,初始化dp[k][j]相当于求右边,最后求中间的k时刚好利用前面得到的左右边的值,从而退出中间的结果,其实说白了,这题也可以用递归的方式做,只不过我把递归转化为递推罢了。i到j的牌简单表示如下:i ,i+1 ,k(i+2,i+3……j-2),j-1,j当最后取出的牌是k(k可能是i+2,i+3……j-2中的一个)时,当然也可能最后取出的牌是i+1或j-1,反正取全部中的最小值就是了,dp[i][j]=min(card[i]*card[k]*card[j]+dp[k][j]+dp[i][k]),k=i+2~j-2;而此时的dp[i][k]和dp[k][j]必须先求出来,其实一开始没想这么多,看dp[i][j]中的j必须比i至少大2时,就应该想到枚举k时只能从i+2开始,j-2结束!!!而i+1和j-1必须先求!!!结论:递推式是由左右两边推出来的式子,一般要先在左右两边的边界进行初始化!!!*/int main(){ //freopen("D:\\in.txt","r",stdin); int i,j,k,n; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) { scanf("%d",&card[i]); } memset(dp,0,sizeof(dp)); for(i=n-2;i>=1;i--) { for(j=i+2;j<=n;j++) { dp[i][j]=card[i+1]*card[i]*card[j]+dp[i+1][j];//删除左边边界i+1 dp[i][j]=min(dp[i][j],card[j-1]*card[i]*card[j]+dp[i][j-1]);//删除右边边界j-1 for(k=i+2;k<=j-2;k++) { dp[i][j]=min(dp[i][k]+card[k]*card[i]*card[j]+dp[k][j],dp[i][j]); } } } printf("%d\n",dp[1][n]); } return 0;}
0 0
- Multiplication Puzzle(区间DP:类似矩阵连乘问题的DP模板)
- POJ-1651 Multiplication Puzzle 矩阵连乘问题(区间dp)
- POJ 1651 Multiplication Puzzle (区间dp 矩阵连乘)
- POJ1651:Multiplication Puzzle(区间DP 最优矩阵链乘)
- poj1651-Multiplication Puzzle-区间dp/矩阵链乘
- 区间DP-矩阵连乘问题
- POJ 1651 Multiplication Puzzle (区间DP/矩阵链乘优化)
- poj 1651 Multiplication Puzzle(区间dp 矩阵链乘法)
- 基于DP的矩阵连乘问题
- 矩阵连乘问题(dp)
- DP 矩阵连乘问题
- 矩阵连乘问题 DP
- DP---矩阵连乘问题
- 矩阵连乘问题 DP
- dp:矩阵连乘问题
- poj 1651 Multiplication Puzzle(区间DP,直接用矩阵相乘的方式也对)
- 区间DP-由矩阵连乘所想到的
- POJ1651 Multiplication Puzzle —— DP 最优矩阵链乘
- ocp-303
- poj2398Toy Storage(叉积+二分)
- ocp-304
- ocp-305
- 例10-10 uva10491(简单概率)
- Multiplication Puzzle(区间DP:类似矩阵连乘问题的DP模板)
- 记:CVTE校招软件类笔试
- mysql出现Duplicate entry '0' for key 'PRIMARY'的错误
- POSIX 最大时间
- UVAlive 7037 - The Problem Needs 3D Arrays(网络流‘最大密度子图)
- 例10-11 uva11181
- jsp页面基础知识--如何导入js和css
- 请描述一下 cookies,sessionStorage 和 localStorage 的区别?
- 海量数据挖掘MMDS week3:社交网络之社区检测:高级技巧