YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题目大意:

有n个数,每次操作选择移除一个数,代价为这个数左边的数乘以这个数再乘以这个数右边的数,不可以移除第一个数和最后一个数,问最小代价。

题解:定义状态dp[l][r]区间l,r需要的最小代价,状态转移 dp[l][r]=min(dp[l][i]+dp[i][r]+arr[i]*arr[l]*arr[r]),就是枚举区间l,r进行转移。

注:我是这样枚举的dp[l][i]+dp[i+1][r]+min(arr[l]*arr[i]*arr[i+1]+arr[i+1]*arr[r]*arr[l],arr[i]*arr[i+1]*arr[r]+arr[l]*arr[r]*arr[i]),感觉没错啊,但是一直wa......

code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
const ll N=100+7;
ll dp[N][N];
ll arr[N]; 
int main(){
    ll n;
    while(cin>>n){
        for(ll i=1;i<=n;i++) cin>>arr[i];
        memset(dp,0,sizeof dp);
        for(ll i=2;i<=n-1;i++) dp[i-1][i+1]=arr[i]*arr[i-1]*arr[i+1];
        for(ll len=4;len<=n;len++){
            for(ll l=1,r=len;r<=n;r++,l++){
                ll cnt=1000000000+7;
                for(int i=l+1;i<=r-1;i++){
                    cnt=min(cnt,dp[l][i]+dp[i][r]+arr[i]*arr[l]*arr[r]); 
                }
                dp[l][r]=cnt;
            }
        }
        cout<<dp[1][n]<<endl;
    }
    return 0;
}

 

posted on 2020-05-19 18:33  Target--fly  阅读(130)  评论(0编辑  收藏  举报