Time Limit:10s Memory Limit:1024MByte
Submissions:385Solved:153
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.
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.
题目大意:
每一次选择一个数,得到的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]));
}
}