【动态规划DP,二维动归】poj1651,Multiplication Puzzle

http://poj.org/problem?id=1651


有N张写有数字的卡片排成一行,按一定次序从中拿走N-2张(第1张和最后一张不能拿),每次只拿一张,取走一张卡片的同时,会得到一个分数,分值的计算方法是:要拿的卡片,和它左右两边的卡片,这三张卡片上数字的乘积。按不同的顺序取走N-2张卡片,得到的总分可能不相同,求出给定一组卡片按上述规则拿取的最小得分。


思路,对于i,j之间的任意一个k都可能是最后一个拿走的,所以:

opt(i, j) = opt(i, k) + opt(k, j) + a[i]*a[k]*a[j], k belongs to (i, j)。

大区间以来小区间,所以从 l=3一次开始动归。

# include<iostream>
# include<string.h>
using namespace std;

# define N 103
# define INF_MAX 10000000

int a[N],state[N][N];

int main()
{
	int i,j,k,l,n;
	cin>>n;
	for(i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	memset(state,0,sizeof(state));
	for(i=1;i<=n-2;i++)
	{
		state[i][i+2]=a[i]*a[i+1]*a[i+2];
	}
	for(l=3;l<=n-1;l++)// for each length
	{
		for(i=1;i<=n-l;i++)
		{
			j=i+l;
			state[i][j]=INF_MAX;
			for(k=i+1;k<=j-1;k++)
			{
				state[i][j]= state[i][j]<state[i][k]+state[k][j]+a[i]*a[k]*a[j]? state[i][j]:state[i][k]+state[k][j]+a[i]*a[k]*a[j];
			}
		}
	}
	cout<<state[1][n]<<endl;

	return 0;
}



你可能感兴趣的:(Multiplication,动态规划DP,二维动归,poj1651,Puzzl)