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

来源:互联网 发布:兄贵音源软件 编辑:程序博客网 时间:2024/05/03 17:51

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 ownvalue.You are asked to pick up all the coins to get maximum value. If the you pickcoini (1 ≤ i ≤n-2), you will getvalue[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 ≤103) — 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]));    }}






0 0