zoukankan      html  css  js  c++  java
  • POJ 1651 Multiplication Puzzle(区间DP)

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

    题目大意:
    给你n个数,可以取[2,n-1]的数,若取a[i]则花费是a[i]与和a[i]相邻两数的乘积,比如有5个数字10 1 50 20 5,
    玩家可以依次拿走1、20、50,总花费10 * 1 * 50 + 50 * 20 * 5 + 10 * 50 * 5 = 500 + 5000 + 2500 = 8000。
    依次拿走50、20、1,总花费1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150。
    求最小的总花费。
    解题思路:
    dp[i][j]表示取完[i+1,j-1]内的数的最小花费。
    于是得到状态转移方程:dp[i][j]=min(dp[i][j],dp[i][k+1]+dp[k+1][j]+a[i]*a[k+1]*a[j]),(i<k+1<j)
    还是菜啊,之前想的状态转移方程是dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j])差一点。。。

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long LL;
     7 const int N=205;
     8 const LL INF=1e18;
     9 LL a[N],dp[N][N];
    10 
    11 int main(){
    12     int n;
    13     while(cin>>n){
    14         for(int i=1;i<=n;i++){
    15             cin>>a[i];
    16         }
    17         for(int len=2;len<n;len++){
    18             for(int i=1;i+len<=n;i++){
    19                 int j=i+len;
    20                 dp[i][j]=INF;
    21                 //枚举删除[i+1,j-1]内的数
    22                 for(int k=i;k<j-1;k++){
    23                     dp[i][j]=min(dp[i][j],dp[i][k+1]+dp[k+1][j]+a[i]*a[k+1]*a[j]);
    24                 }
    25             }
    26         }
    27         cout<<dp[1][n]<<endl;
    28     }
    29     return 0;
    30 }
  • 相关阅读:
    Vue生命周期
    事件
    改变this指向
    全屏要素
    微信小程序
    编程心得
    设计模式-单例与实例化
    第五节课 课堂总结
    作业四 分支结构
    课堂总结
  • 原文地址:https://www.cnblogs.com/fu3638/p/8860088.html
Copyright © 2011-2022 走看看