玲珑学院OJ 1074 Pick Up Coins【区间dp】

1074 - Pick Up Coins

Time Limit:10s Memory Limit:1024MByte

Submissions:385Solved:153

DESCRIPTION

There are n coins in a line, indexed from 0 to n-1. Each coin has its own value.You are asked to pick up all the coins to get maximum value. If the you pick coini (1 ≤ i ≤n-2), you will get value[left]×value[i]×value[right]value[left]×value[i]×value[right] coin value. Here left and right are adjacent indices of i. After the picked, the left and right then becomes adjacent.

Note.

If you pick the first coin, you can assume the value[left] is 1.

If you pick the last coin, you can assume the value[right] is 1.

Find the maximum value when you pick up all the coins.

INPUT
The first line is a single integer TT, indicating the number of test cases.
For each test case:
The first line contains a number nn (3≤ nn ≤10 3) — The number of magic coins.
The second line contains nn numbers ( all numbers ≤10) — The value of each coin.
OUTPUT
For each test case, return a number indicates the maximum value after you picked up all the coins.
SAMPLE INPUT
1
3
3 5 8
SAMPLE OUTPUT
152
HINT
Hint In the sample, answer = 120 + 24 + 8 = 152 [3,5,8] --> [3,8] --> [8]

题目大意:

每一次选择一个数,得到的val是这个数和两边的数的乘积,求最大值。


1、观察到数据范围以及操作方式,很显然的一道区间dp的问题,矩阵连乘最大操作数问题。

设定dp【i】【j】表示已经拿完了区间:【i,j-1】的所有数之后的最小总价值。


2、那么其状态转移方程的重点放在区间合并上来:

dp【i】【j】=min(dp【i】【j】,dp【i】【k】+dp【k+1】【j】+a【k】*a【j】*a【i-1】);


3、那么ans-dp【1】【n】+a【0】*a【n-1】+max(a【0】,a【n-1】);


Ac代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int dp[1250][1250];
int a[1250];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        memset(dp,0,sizeof(dp));
        for(int len=1;len<n;len++)
        {
            for(int i=1;i<n-1;i++)
            {
                int j=i+len;
                if(j>=n)break;
                for(int k=i;k<j;k++)
                {
                    dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[k]*a[i-1]*a[j]);
                }
            }
        }
        printf("%d\n",dp[1][n-1]+a[0]*a[n-1]+max(a[0],a[n-1]));
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值