POJ1651:Multiplication Puzzle——题解

http://poj.org/problem?id=1651

题目大意:同“乘法游戏”,这里将乘法游戏的题面复制过来。

乘法游戏是在一行牌上进行的。每一张牌包括了一个正整数。在每一个移动中,玩家拿出一张牌,得分是用它的数字乘以它左边和右边的数,所以不允许拿第1张和最后1张牌。最后一次移动后,这里只剩下两张牌。你的目标是使得分的和最小。

———————————————————————————————————

太水了……

(其实是以前做过,所以觉得水……)

dp[i][j]表示i~j区间做乘法游戏得到的最小值。

显然长度为3的时候别无选择只能拿中间的。

那么剩下的情况可以为:枚举最后拿的数,递归左右边,最后显然乘起来的就是左右边界和最后的这一个数。

#include<cstdio>
using namespace std;
int a[101];
int dp[101][101]={0};
const int INF=99999999;
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        dp[i][i+1]=0;
    }
    for(int i=1;i<=n-2;i++){
        dp[i][i+2]=a[i]*a[i+2]*a[i+1];
    }
    for(int i=3;i<=n-1;i++){
        for(int j=1;j<=n-i;j++){
            dp[j][j+i]=INF;
            for(int k=j+1;k<=j+i-1;k++){
                if(dp[j][j+i]>dp[j][k]+dp[k][j+i]+a[j]*a[k]*a[j+i])
                dp[j][j+i]=dp[j][k]+dp[k][j+i]+a[j]*a[k]*a[j+i];
            }
        }
    }
    printf("%d\n",dp[1][n]);
    return 0;
}
posted @ 2018-01-08 16:09  luyouqi233  阅读(360)  评论(0编辑  收藏  举报