原题链接
Problem Description
The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one card out of the row and scores the number of points equal to the product of the number on the card taken and the numbers on the cards on the left and on the right of it. It is not allowed to take out the first and the last card in the row. After the final move, only two cards are left in the row.
The goal is to take cards in such order as to minimize the total number of scored points.
For example, if cards in the row contain numbers 10 1 50 20 5, player might take a card with 1, then 20 and 50, scoring
10*1*50 + 50*20*5 + 10*50*5 = 500+5000+2500 = 8000
If he would take the cards in the opposite order, i.e. 50, then 20, then 1, the score would be
1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150.
Input
The first line of the input contains the number of cards N (3 <= N <= 100). The second line contains N integers in the range from 1 to 100, separated by spaces.
Output
Output must contain a single integer - the minimal score.
Sample Input
6
10 1 50 50 20 5
Sample Output
3650
题目大意
有一组数,现在可以任取其中三个连续的数,随后给答案贡献三个数的积,并删除中间的数,重复以上操作,直到无法再取,问答案最小是多少。
解题思路
区间DP基本做法,第一层循环枚举长度len,第二层循环枚举起点i,第三层循环枚举中间断点k,注意合并操作。
AC代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<string>
#include<queue>
#include<list>
#include<stack>
#include<set>
#include<map>
#define ll long long
#define ull unsigned long long
#define rep(i,a,b) for (int i=(a),_ed=(b);i<_ed;i++)
#define fil(a,b) memset((a),(b),sizeof(a))
#define cl(a) fil(a,0)
#define pb push_back
#define mp make_pair
#define PI 3.1415927
#define inf 0x3f3f3f3f
#define fi first
#define se second
#define VII vector<int,int>
using namespace std;
int cards[105];
int d[105][105];
int MinScore(int n)
{
cl(d);
int len;
for (len = 1; len < n; len++)
{
int i, j, k;
for (i = 1, j = len+1; j < n; i++, j++)
{
int mina = inf;
for (k = i; k < j; k++)
{
int counta = d[i][k] + d[k+1][j] + cards[i-1]*cards[k]*cards[j];
if (counta < mina)
{
mina = counta;
}
}
d[i][j] = mina;
}
}
return d[1][n-1];
}
int main(void)
{
int ncards;
while (scanf("%d", &ncards) != EOF)
{
int i;
for (i = 0; i < ncards; i++)
{
scanf("%d", &cards[i]);
}
printf("%d\n", MinScore(ncards));
}
return 0;
}