XDOJ1326:生命仪式(环形区间dp)




1326: 生命仪式

时间限制: 5 Sec   内存限制: 128 MB
提交: 12   解决: 7

题目描述

tsy的另一个身份是一位mo法师,他准备进行一个生命延续的仪式(为一位长者),仪式的规则是这样的,N个人围成一圈(N号与1号相邻,其余依次相邻),每个人有一个能量值ai,每次选取圈内的一个人进行献祭,这个人立刻退(ren)出(jian)仪(zheng)式(fa),而长者则得到一些时间,时间的大小为选取人选和当前左右两人的能量之积(左右两人在还剩两人时是重复的),最后还剩一人时仪式结束,现在问你怎样操作这个仪式可以使得长者得到的时间总量最大。

输入

多组数据

每组第一行一个数字N代表人数(2 <= N <= 400)

之后N个数字ai代表第i人的能量值(ai <= 150)

输出

一行一个数字,代表得到的最大时间

样例输入

2
4 2

样例输出

32

提示

这不是贪心


来源

软院科协2017级新生赛


环形区间DP的模版题

一个操作代表权值,最后有一个终止条件。

思考什么时候终止便可以得到状态

很显然只剩下一个的时候游戏终止 则状态可以表示为区间i j 取到只剩下i的时候的最大值

状态转移方程

dp[i][j]=max(,dp[i][k]+dp[k+1][j]+a[i]*a[k+1]*a[j+1])

或者也可以将状态标示为剩下I j 其实大体思路是一样的。

#include
using namespace std;
const int maxn=410;
long long a[maxn]; 
//相当于合并石子的逆过程
// 
long long dp[maxn][maxn];
typedef long long ll;
ll read(){ 
    ll x=0,f=1;char ch=getchar(); 
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 
    return f*x; 
}
// 
//dp [i][j] max(dp[i][j],dp[k+1][k-1]+a[k+1]*a[k]*a[k-1]);
int N;
int main(){
	    while(~scanf("%d",&N))
	    {
		for(int i=0;i


你可能感兴趣的:(ACM)