ZJU 1602 Multiplication Puzzle

#include<iostream>
#include<cstring>
#define M 101
using namespace std;
/*
2588443 2011-07-20 22:40:30 Accepted  1602 C++ 0 188 ashione 
题目解法:

当我们从最后一步去倒推的时候就可以发现,比如最后一个拿走1,
这一列数可以得到的最小分数是10*1*5+拿走1到5的总分+拿走10到1的总分。
这与你如何拿走1到5和拿走10到1没有关系,符合DP的无后效性。
于是,我们可以根据此写出DP的递推式:

sorce[i][j]=min{sorce[i,k]+sorce[k][j]}+card[i]*card[k]*card[j] (i<k<j)

其中sorce[i,j]表示拿走第i张牌与第j张牌之间的牌最小的得分,card[i]表示的i张牌的分数。
我们通过枚举最后一个拿走的牌k就可以求出sorce[i][j]的最小值。最后答案为sorce[1][n]。

其中delta为步长增量,由1->(n-1)递增。

*/
int main(){
	int sorce[M][M],card[M],i,j,k,delta,n;
	while(cin>>n){

		for(i=1;i<=n;i++)
			cin>>card[i];

		memset(sorce,0,sizeof(sorce));

		for(delta=1;delta<n;delta++){

			for(i=1;i<=n-delta;i++){

				j=i+delta;

				for(k=i+1;k<j;k++){

					int t=card[i]*card[k]*card[j]+sorce[i][k]+sorce[k][j];

					if(t<sorce[i][j] || sorce[i][j]==0)
						sorce[i][j]=t;
				}
			}
		}

		cout<<sorce[1][n]<<endl;
	}
	return 0;
}
//http://blog.163.com/lzoi_xzf/blog/static/169678204201072641756410/

你可能感兴趣的:(ZJU 1602 Multiplication Puzzle)