【动态规划】环形区间dp: 能量项链_leetcode

本题和合并石子果子一样,都是枚举最后一次合并的点

【动态规划笔记】区间dp:合并果子_m0_52043808的博客

区别:

1、需要断环为链

2、每一堆石子变为两个值,这里用结构体实现

3、每一次合并多出的值由第一个区间第一个珠子的head和第二个区间第一个珠子的head和最后一个珠子的tail相乘得到(模拟)

#include<iostream>
using namespace std;
int n;
int b[201];
int dp[202][202];
struct node{
	int head,tail;
}a[201];

int main(){
cin>>n;


for(int i=1;i<=n;i++){
	cin>>b[i];
	b[i+n]=b[i];
}
for(int i=1;i<=2*n-1;i++){
	a[i].head=b[i];
	a[i].tail=b[i+1];
}
a[2*n].head=b[n];
a[2*n].tail=b[1];
for(int len=2;len<=n;len++){
	for(int i=1;i+len-1<=2*n;i++){
		int j=i+len-1;
		for(int k=i;k<j;k++){
			dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i].head*a[k].tail*a[j].tail);
		}
	}
}

int res=0;
for(int i=1;i<=n;i++){
	res=max(res,dp[i][i+n-1]);
}
cout<<res;
return 0;
	
}

代码2:

#include<iostream>
using namespace std;
int n;
int c[201];
int a[201];
int b[201];
int dp[201][201];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>c[i];
    }
    for(int i=1;i<n;i++){
        a[i]=c[i];
        b[i]=c[i+1];
    }

    a[n]=c[n];b[n]=c[1];
    for(int i=n+1;i<=2*n;i++){
        a[i]=a[i-n];
        b[i]=b[i-n];
    }
    // for(int i=1;i<=2*n;i++){
    //     cout<<a[i]<<" "<<b[i]<<endl;
    // }
    for(int len=2;len<=n;len++){
     for(int i=1;i+len-1<=2*n;i++){
         int j=i+len-1;
         for(int k=i;k<j;k++)
       dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+a[i]*b[k]*b[j]);
     }
    }
    int res=0;
    for(int i=1;i<=n;i++){
        res=max(res,dp[i][i+n-1]);
    }
    cout<<res;
    return 0;
}